* added SFTP support

* Fixed bug with reference URL fields (for SearchURL)
* check for ART and display warning
This commit is contained in:
Philipp Crocoll 2013-12-31 09:46:57 +01:00
parent 5e7f489e76
commit e27c4fa727
169 changed files with 29140 additions and 262 deletions

View File

@ -6,4 +6,8 @@
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
-->
<remove-node path="/api/package[@name='com.jcraft.jsch']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jce']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jcraft']" />
<remove-node path="/api/package[@name='com.jcraft.jzlib']" />
</metadata>

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>

View File

@ -0,0 +1,18 @@
using Android.Content;
#if !EXCLUDE_JAVAFILESTORAGE
namespace keepass2android.Io
{
public class SftpFileStorage: JavaFileStorage
{
public SftpFileStorage(IKp2aApp app) :
base(new Keepass2android.Javafilestorage.SftpStorage(), app)
{
}
}
}
#endif

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@ -67,6 +67,7 @@
<Compile Include="Io\IFileStorage.cs" />
<Compile Include="Io\IoUtil.cs" />
<Compile Include="Io\JavaFileStorage.cs" />
<Compile Include="Io\SftpFileStorage.cs" />
<Compile Include="Io\SkyDriveFileStorage.cs" />
<Compile Include="IProgressDialog.cs" />
<Compile Include="PreferenceKey.cs" />
@ -96,6 +97,11 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SearchDbHelper.cs" />
<Compile Include="ProgressDialogStatusLogger.cs" />
<Compile Include="Utils\EntryUtil.cs" />
<Compile Include="Utils\Spr\SprContext.cs" />
<Compile Include="Utils\Spr\SprEncoding.cs" />
<Compile Include="Utils\Spr\SprEngine.cs" />
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">

View File

@ -17,6 +17,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using KeePass.Util.Spr;
using KeePassLib;
using KeePassLib.Collections;
using KeePassLib.Interfaces;
@ -104,7 +105,9 @@ namespace keepass2android
return pgResults;
foreach (PwEntry entry in database.Entries.Values)
{
String otherHost = ExtractHost(entry.Strings.ReadSafe(PwDefs.UrlField));
string otherUrl = entry.Strings.ReadSafe(PwDefs.UrlField);
otherUrl = SprEngine.Compile(otherUrl, new SprContext(entry, database.KpDatabase, SprCompileFlags.References));
String otherHost = ExtractHost(otherUrl);
if ((allowSubdomains) && (otherHost.StartsWith("www.")))
otherHost = otherHost.Substring(4); //remove "www."
if (String.IsNullOrWhiteSpace(otherHost))

View File

@ -592,16 +592,6 @@ namespace KeePass.Util.Spr
return (strText.IndexOf('{') >= 0);
}
internal static string DerefFn(string str, PwEntry pe)
{
if(!MightDeref(str)) return str;
SprContext ctx = new SprContext(pe,
App.Kp2a.GetDb().KpDatabase,
SprCompileFlags.Deref);
// ctx.ForcePlainTextPasswords = false;
return Compile(str, ctx);
}
}
}

View File

@ -0,0 +1,294 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class Buffer{
final byte[] tmp=new byte[4];
byte[] buffer;
int index;
int s;
public Buffer(int size){
buffer=new byte[size];
index=0;
s=0;
}
public Buffer(byte[] buffer){
this.buffer=buffer;
index=0;
s=0;
}
public Buffer(){ this(1024*10*2); }
public void putByte(byte foo){
buffer[index++]=foo;
}
public void putByte(byte[] foo) {
putByte(foo, 0, foo.length);
}
public void putByte(byte[] foo, int begin, int length) {
System.arraycopy(foo, begin, buffer, index, length);
index+=length;
}
public void putString(byte[] foo){
putString(foo, 0, foo.length);
}
public void putString(byte[] foo, int begin, int length) {
putInt(length);
putByte(foo, begin, length);
}
public void putInt(int val) {
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index, 4);
index+=4;
}
public void putLong(long val) {
tmp[0]=(byte)(val >>> 56);
tmp[1]=(byte)(val >>> 48);
tmp[2]=(byte)(val >>> 40);
tmp[3]=(byte)(val >>> 32);
System.arraycopy(tmp, 0, buffer, index, 4);
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index+4, 4);
index+=8;
}
void skip(int n) {
index+=n;
}
void putPad(int n) {
while(n>0){
buffer[index++]=(byte)0;
n--;
}
}
public void putMPInt(byte[] foo){
int i=foo.length;
if((foo[0]&0x80)!=0){
i++;
putInt(i);
putByte((byte)0);
}
else{
putInt(i);
}
putByte(foo);
}
public int getLength(){
return index-s;
}
public int getOffSet(){
return s;
}
public void setOffSet(int s){
this.s=s;
}
public long getLong(){
long foo = getInt()&0xffffffffL;
foo = ((foo<<32)) | (getInt()&0xffffffffL);
return foo;
}
public int getInt(){
int foo = getShort();
foo = ((foo<<16)&0xffff0000) | (getShort()&0xffff);
return foo;
}
public long getUInt(){
long foo = 0L;
long bar = 0L;
foo = getByte();
foo = ((foo<<8)&0xff00)|(getByte()&0xff);
bar = getByte();
bar = ((bar<<8)&0xff00)|(getByte()&0xff);
foo = ((foo<<16)&0xffff0000) | (bar&0xffff);
return foo;
}
int getShort() {
int foo = getByte();
foo = ((foo<<8)&0xff00)|(getByte()&0xff);
return foo;
}
public int getByte() {
return (buffer[s++]&0xff);
}
public void getByte(byte[] foo) {
getByte(foo, 0, foo.length);
}
void getByte(byte[] foo, int start, int len) {
System.arraycopy(buffer, s, foo, start, len);
s+=len;
}
public int getByte(int len) {
int foo=s;
s+=len;
return foo;
}
public byte[] getMPInt() {
int i=getInt(); // uint32
if(i<0 || // bigger than 0x7fffffff
i>8*1024){
// TODO: an exception should be thrown.
i = 8*1024; // the session will be broken, but working around OOME.
}
byte[] foo=new byte[i];
getByte(foo, 0, i);
return foo;
}
public byte[] getMPIntBits() {
int bits=getInt();
int bytes=(bits+7)/8;
byte[] foo=new byte[bytes];
getByte(foo, 0, bytes);
if((foo[0]&0x80)!=0){
byte[] bar=new byte[foo.length+1];
bar[0]=0; // ??
System.arraycopy(foo, 0, bar, 1, foo.length);
foo=bar;
}
return foo;
}
public byte[] getString() {
int i = getInt(); // uint32
if(i<0 || // bigger than 0x7fffffff
i>256*1024){
// TODO: an exception should be thrown.
i = 256*1024; // the session will be broken, but working around OOME.
}
byte[] foo=new byte[i];
getByte(foo, 0, i);
return foo;
}
byte[] getString(int[]start, int[]len) {
int i=getInt();
start[0]=getByte(i);
len[0]=i;
return buffer;
}
public void reset(){
index=0;
s=0;
}
public void shift(){
if(s==0)return;
System.arraycopy(buffer, s, buffer, 0, index-s);
index=index-s;
s=0;
}
void rewind(){
s=0;
}
byte getCommand(){
return buffer[5];
}
void checkFreeSize(int n){
if(buffer.length<index+n){
byte[] tmp = new byte[buffer.length*2];
System.arraycopy(buffer, 0, tmp, 0, index);
buffer = tmp;
}
}
byte[][] getBytes(int n, String msg) throws JSchException {
byte[][] tmp = new byte[n][];
for(int i = 0; i < n; i++){
int j = getInt();
if(getLength() < j){
throw new JSchException(msg);
}
tmp[i] = new byte[j];
getByte(tmp[i]);
}
return tmp;
}
/*
static Buffer fromBytes(byte[]... args){
int length = args.length*4;
for(int i = 0; i < args.length; i++){
length += args[i].length;
}
Buffer buf = new Buffer(length);
for(int i = 0; i < args.length; i++){
buf.putString(args[i]);
}
return buf;
}
*/
static Buffer fromBytes(byte[][] args){
int length = args.length*4;
for(int i = 0; i < args.length; i++){
length += args[i].length;
}
Buffer buf = new Buffer(length);
for(int i = 0; i < args.length; i++){
buf.putString(args[i]);
}
return buf;
}
/*
static String[] chars={
"0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
};
static void dump_buffer(){
int foo;
for(int i=0; i<tmp_buffer_index; i++){
foo=tmp_buffer[i]&0xff;
System.err.print(chars[(foo>>>4)&0xf]);
System.err.print(chars[foo&0xf]);
if(i%16==15){
System.err.println("");
continue;
}
if(i>0 && i%2==1){
System.err.print(" ");
}
}
System.err.println("");
}
static void dump(byte[] b){
dump(b, 0, b.length);
}
static void dump(byte[] b, int s, int l){
for(int i=s; i<s+l; i++){
System.err.print(Integer.toHexString(b[i]&0xff)+":");
}
System.err.println("");
}
*/
}

View File

@ -0,0 +1,677 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
public abstract class Channel implements Runnable{
static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION= 91;
static final int SSH_MSG_CHANNEL_OPEN_FAILURE= 92;
static final int SSH_MSG_CHANNEL_WINDOW_ADJUST= 93;
static final int SSH_OPEN_ADMINISTRATIVELY_PROHIBITED= 1;
static final int SSH_OPEN_CONNECT_FAILED= 2;
static final int SSH_OPEN_UNKNOWN_CHANNEL_TYPE= 3;
static final int SSH_OPEN_RESOURCE_SHORTAGE= 4;
static int index=0;
private static java.util.Vector pool=new java.util.Vector();
static Channel getChannel(String type){
if(type.equals("session")){
return new ChannelSession();
}
if(type.equals("shell")){
return new ChannelShell();
}
if(type.equals("exec")){
return new ChannelExec();
}
if(type.equals("x11")){
return new ChannelX11();
}
if(type.equals("auth-agent@openssh.com")){
return new ChannelAgentForwarding();
}
if(type.equals("direct-tcpip")){
return new ChannelDirectTCPIP();
}
if(type.equals("forwarded-tcpip")){
return new ChannelForwardedTCPIP();
}
if(type.equals("sftp")){
return new ChannelSftp();
}
if(type.equals("subsystem")){
return new ChannelSubsystem();
}
return null;
}
static Channel getChannel(int id, Session session){
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Channel c=(Channel)(pool.elementAt(i));
if(c.id==id && c.session==session) return c;
}
}
return null;
}
static void del(Channel c){
synchronized(pool){
pool.removeElement(c);
}
}
int id;
volatile int recipient=-1;
protected byte[] type=Util.str2byte("foo");
volatile int lwsize_max=0x100000;
volatile int lwsize=lwsize_max; // local initial window size
volatile int lmpsize=0x4000; // local maximum packet size
volatile long rwsize=0; // remote initial window size
volatile int rmpsize=0; // remote maximum packet size
IO io=null;
Thread thread=null;
volatile boolean eof_local=false;
volatile boolean eof_remote=false;
volatile boolean close=false;
volatile boolean connected=false;
volatile boolean open_confirmation=false;
volatile int exitstatus=-1;
volatile int reply=0;
volatile int connectTimeout=0;
private Session session;
int notifyme=0;
Channel(){
synchronized(pool){
id=index++;
pool.addElement(this);
}
}
synchronized void setRecipient(int foo){
this.recipient=foo;
if(notifyme>0)
notifyAll();
}
int getRecipient(){
return recipient;
}
void init() throws JSchException {
}
public void connect() throws JSchException{
connect(0);
}
public void connect(int connectTimeout) throws JSchException{
this.connectTimeout=connectTimeout;
try{
sendChannelOpen();
start();
}
catch(Exception e){
connected=false;
disconnect();
if(e instanceof JSchException)
throw (JSchException)e;
throw new JSchException(e.toString(), e);
}
}
public void setXForwarding(boolean foo){
}
public void start() throws JSchException{}
public boolean isEOF() {return eof_remote;}
void getData(Buffer buf){
setRecipient(buf.getInt());
setRemoteWindowSize(buf.getUInt());
setRemotePacketSize(buf.getInt());
}
public void setInputStream(InputStream in){
io.setInputStream(in, false);
}
public void setInputStream(InputStream in, boolean dontclose){
io.setInputStream(in, dontclose);
}
public void setOutputStream(OutputStream out){
io.setOutputStream(out, false);
}
public void setOutputStream(OutputStream out, boolean dontclose){
io.setOutputStream(out, dontclose);
}
public void setExtOutputStream(OutputStream out){
io.setExtOutputStream(out, false);
}
public void setExtOutputStream(OutputStream out, boolean dontclose){
io.setExtOutputStream(out, dontclose);
}
public InputStream getInputStream() throws IOException {
PipedInputStream in=
new MyPipedInputStream(
32*1024 // this value should be customizable.
);
io.setOutputStream(new PassiveOutputStream(in), false);
return in;
}
public InputStream getExtInputStream() throws IOException {
PipedInputStream in=
new MyPipedInputStream(
32*1024 // this value should be customizable.
);
io.setExtOutputStream(new PassiveOutputStream(in), false);
return in;
}
public OutputStream getOutputStream() throws IOException {
/*
PipedOutputStream out=new PipedOutputStream();
io.setInputStream(new PassiveInputStream(out
, 32*1024
), false);
return out;
*/
final Channel channel=this;
OutputStream out=new OutputStream(){
private int dataLen=0;
private Buffer buffer=null;
private Packet packet=null;
private boolean closed=false;
private synchronized void init() throws java.io.IOException{
buffer=new Buffer(rmpsize);
packet=new Packet(buffer);
byte[] _buf=buffer.buffer;
if(_buf.length-(14+0)-Session.buffer_margin<=0){
buffer=null;
packet=null;
throw new IOException("failed to initialize the channel.");
}
}
byte[] b=new byte[1];
public void write(int w) throws java.io.IOException{
b[0]=(byte)w;
write(b, 0, 1);
}
public void write(byte[] buf, int s, int l) throws java.io.IOException{
if(packet==null){
init();
}
if(closed){
throw new java.io.IOException("Already closed");
}
byte[] _buf=buffer.buffer;
int _bufl=_buf.length;
while(l>0){
int _l=l;
if(l>_bufl-(14+dataLen)-Session.buffer_margin){
_l=_bufl-(14+dataLen)-Session.buffer_margin;
}
if(_l<=0){
flush();
continue;
}
System.arraycopy(buf, s, _buf, 14+dataLen, _l);
dataLen+=_l;
s+=_l;
l-=_l;
}
}
public void flush() throws java.io.IOException{
if(closed){
throw new java.io.IOException("Already closed");
}
if(dataLen==0)
return;
packet.reset();
buffer.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buffer.putInt(recipient);
buffer.putInt(dataLen);
buffer.skip(dataLen);
try{
int foo=dataLen;
dataLen=0;
synchronized(channel){
if(!channel.close)
getSession().write(packet, channel, foo);
}
}
catch(Exception e){
close();
throw new java.io.IOException(e.toString());
}
}
public void close() throws java.io.IOException{
if(packet==null){
try{
init();
}
catch(java.io.IOException e){
// close should be finished silently.
return;
}
}
if(closed){
return;
}
if(dataLen>0){
flush();
}
channel.eof();
closed=true;
}
};
return out;
}
class MyPipedInputStream extends PipedInputStream{
MyPipedInputStream() throws IOException{ super(); }
MyPipedInputStream(int size) throws IOException{
super();
buffer=new byte[size];
}
MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); }
MyPipedInputStream(PipedOutputStream out, int size) throws IOException{
super(out);
buffer=new byte[size];
}
/*
* TODO: We should have our own Piped[I/O]Stream implementation.
* Before accepting data, JDK's PipedInputStream will check the existence of
* reader thread, and if it is not alive, the stream will be closed.
* That behavior may cause the problem if multiple threads make access to it.
*/
public synchronized void updateReadSide() throws IOException {
if(available() != 0){ // not empty
return;
}
in = 0;
out = 0;
buffer[in++] = 0;
read();
}
}
void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
void setLocalWindowSize(int foo){ this.lwsize=foo; }
void setLocalPacketSize(int foo){ this.lmpsize=foo; }
synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; }
synchronized void addRemoteWindowSize(int foo){
this.rwsize+=foo;
if(notifyme>0)
notifyAll();
}
void setRemotePacketSize(int foo){ this.rmpsize=foo; }
public void run(){
}
void write(byte[] foo) throws IOException {
write(foo, 0, foo.length);
}
void write(byte[] foo, int s, int l) throws IOException {
try{
io.put(foo, s, l);
}catch(NullPointerException e){}
}
void write_ext(byte[] foo, int s, int l) throws IOException {
try{
io.put_ext(foo, s, l);
}catch(NullPointerException e){}
}
void eof_remote(){
eof_remote=true;
try{
io.out_close();
}
catch(NullPointerException e){}
}
void eof(){
if(eof_local)return;
eof_local=true;
try{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
buf.putInt(getRecipient());
synchronized(this){
if(!close)
getSession().write(packet);
}
}
catch(Exception e){
//System.err.println("Channel.eof");
//e.printStackTrace();
}
/*
if(!isConnected()){ disconnect(); }
*/
}
/*
http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt
5.3 Closing a Channel
When a party will no longer send more data to a channel, it SHOULD
send SSH_MSG_CHANNEL_EOF.
byte SSH_MSG_CHANNEL_EOF
uint32 recipient_channel
No explicit response is sent to this message. However, the
application may send EOF to whatever is at the other end of the
channel. Note that the channel remains open after this message, and
more data may still be sent in the other direction. This message
does not consume window space and can be sent even if no window space
is available.
When either party wishes to terminate the channel, it sends
SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
message for the channel. The channel is considered closed for a
party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
the party may then reuse the channel number. A party MAY send
SSH_MSG_CHANNEL_CLOSE without having sent or received
SSH_MSG_CHANNEL_EOF.
byte SSH_MSG_CHANNEL_CLOSE
uint32 recipient_channel
This message does not consume window space and can be sent even if no
window space is available.
It is recommended that any data sent before this message is delivered
to the actual destination, if possible.
*/
void close(){
if(close)return;
close=true;
eof_local=eof_remote=true;
try{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
buf.putInt(getRecipient());
synchronized(this){
getSession().write(packet);
}
}
catch(Exception e){
//e.printStackTrace();
}
}
public boolean isClosed(){
return close;
}
static void disconnect(Session session){
Channel[] channels=null;
int count=0;
synchronized(pool){
channels=new Channel[pool.size()];
for(int i=0; i<pool.size(); i++){
try{
Channel c=((Channel)(pool.elementAt(i)));
if(c.session==session){
channels[count++]=c;
}
}
catch(Exception e){
}
}
}
for(int i=0; i<count; i++){
channels[i].disconnect();
}
}
public void disconnect(){
//System.err.println(this+":disconnect "+io+" "+connected);
//Thread.dumpStack();
try{
synchronized(this){
if(!connected){
return;
}
connected=false;
}
close();
eof_remote=eof_local=true;
thread=null;
try{
if(io!=null){
io.close();
}
}
catch(Exception e){
//e.printStackTrace();
}
// io=null;
}
finally{
Channel.del(this);
}
}
public boolean isConnected(){
Session _session=this.session;
if(_session!=null){
return _session.isConnected() && connected;
}
return false;
}
public void sendSignal(String signal) throws Exception {
RequestSignal request=new RequestSignal();
request.setSignal(signal);
request.request(getSession(), this);
}
// public String toString(){
// return "Channel: type="+new String(type)+",id="+id+",recipient="+recipient+",window_size="+window_size+",packet_size="+packet_size;
// }
/*
class OutputThread extends Thread{
Channel c;
OutputThread(Channel c){ this.c=c;}
public void run(){c.output_thread();}
}
*/
class PassiveInputStream extends MyPipedInputStream{
PipedOutputStream out;
PassiveInputStream(PipedOutputStream out, int size) throws IOException{
super(out, size);
this.out=out;
}
PassiveInputStream(PipedOutputStream out) throws IOException{
super(out);
this.out=out;
}
public void close() throws IOException{
if(out!=null){
this.out.close();
}
out=null;
}
}
class PassiveOutputStream extends PipedOutputStream{
PassiveOutputStream(PipedInputStream in) throws IOException{
super(in);
}
}
void setExitStatus(int status){ exitstatus=status; }
public int getExitStatus(){ return exitstatus; }
void setSession(Session session){
this.session=session;
}
public Session getSession() throws JSchException{
Session _session=session;
if(_session==null){
throw new JSchException("session is not available");
}
return _session;
}
public int getId(){ return id; }
protected void sendOpenConfirmation() throws Exception{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
buf.putInt(getRecipient());
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
getSession().write(packet);
}
protected void sendOpenFailure(int reasoncode){
try{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
buf.putInt(getRecipient());
buf.putInt(reasoncode);
buf.putString(Util.str2byte("open failed"));
buf.putString(Util.empty);
getSession().write(packet);
}
catch(Exception e){
}
}
protected Packet genChannelOpenPacket(){
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
// uint32 sender channel // 0
// uint32 initial window size // 0x100000(65536)
// uint32 maxmum packet size // 0x4000(16384)
packet.reset();
buf.putByte((byte)90);
buf.putString(this.type);
buf.putInt(this.id);
buf.putInt(this.lwsize);
buf.putInt(this.lmpsize);
return packet;
}
protected void sendChannelOpen() throws Exception {
Session _session=getSession();
if(!_session.isConnected()){
throw new JSchException("session is down");
}
Packet packet = genChannelOpenPacket();
_session.write(packet);
int retry=10;
long start=System.currentTimeMillis();
long timeout=connectTimeout;
if(timeout!=0L) retry = 1;
synchronized(this){
while(this.getRecipient()==-1 &&
_session.isConnected() &&
retry>0){
if(timeout>0L){
if((System.currentTimeMillis()-start)>timeout){
retry=0;
continue;
}
}
try{
long t = timeout==0L ? 5000L : timeout;
this.notifyme=1;
wait(t);
}
catch(java.lang.InterruptedException e){
}
finally{
this.notifyme=0;
}
retry--;
}
}
if(!_session.isConnected()){
throw new JSchException("session is down");
}
if(this.getRecipient()==-1){ // timeout
throw new JSchException("channel is not opened.");
}
if(this.open_confirmation==false){ // SSH_MSG_CHANNEL_OPEN_FAILURE
throw new JSchException("channel is not opened.");
}
connected=true;
}
}

View File

@ -0,0 +1,266 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
import java.util.Vector;
class ChannelAgentForwarding extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
private final byte SSH_AGENT_RSA_RESPONSE = 4;
private final byte SSH_AGENT_FAILURE = 5;
private final byte SSH_AGENT_SUCCESS = 6;
private final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
private final byte SSH2_AGENTC_SIGN_REQUEST=13;
private final byte SSH2_AGENT_SIGN_RESPONSE=14;
private final byte SSH2_AGENTC_ADD_IDENTITY=17;
private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
private final byte SSH2_AGENT_FAILURE=30;
boolean init=true;
private Buffer rbuf=null;
private Buffer wbuf=null;
private Packet packet=null;
private Buffer mbuf=null;
ChannelAgentForwarding(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
type=Util.str2byte("auth-agent@openssh.com");
rbuf=new Buffer();
rbuf.reset();
//wbuf=new Buffer(rmpsize);
//packet=new Packet(wbuf);
mbuf=new Buffer();
connected=true;
}
public void run(){
try{
sendOpenConfirmation();
}
catch(Exception e){
close=true;
disconnect();
}
}
void write(byte[] foo, int s, int l) throws java.io.IOException {
if(packet==null){
wbuf=new Buffer(rmpsize);
packet=new Packet(wbuf);
}
rbuf.shift();
if(rbuf.buffer.length<rbuf.index+l){
byte[] newbuf=new byte[rbuf.s+l];
System.arraycopy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.length);
rbuf.buffer=newbuf;
}
rbuf.putByte(foo, s, l);
int mlen=rbuf.getInt();
if(mlen>rbuf.getLength()){
rbuf.s-=4;
return;
}
int typ=rbuf.getByte();
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
throw new java.io.IOException(e.toString());
}
IdentityRepository irepo = _session.getIdentityRepository();
UserInfo userinfo=_session.getUserInfo();
mbuf.reset();
if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){
mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
Vector identities = irepo.getIdentities();
synchronized(identities){
int count=0;
for(int i=0; i<identities.size(); i++){
Identity identity=(Identity)(identities.elementAt(i));
if(identity.getPublicKeyBlob()!=null)
count++;
}
mbuf.putInt(count);
for(int i=0; i<identities.size(); i++){
Identity identity=(Identity)(identities.elementAt(i));
byte[] pubkeyblob=identity.getPublicKeyBlob();
if(pubkeyblob==null)
continue;
mbuf.putString(pubkeyblob);
mbuf.putString(Util.empty);
}
}
}
else if(typ==SSH_AGENTC_REQUEST_RSA_IDENTITIES) {
mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER);
mbuf.putInt(0);
}
else if(typ==SSH2_AGENTC_SIGN_REQUEST){
byte[] blob=rbuf.getString();
byte[] data=rbuf.getString();
int flags=rbuf.getInt();
// if((flags & 1)!=0){ //SSH_AGENT_OLD_SIGNATURE // old OpenSSH 2.0, 2.1
// datafellows = SSH_BUG_SIGBLOB;
// }
Vector identities = irepo.getIdentities();
Identity identity = null;
synchronized(identities){
for(int i=0; i<identities.size(); i++){
Identity _identity=(Identity)(identities.elementAt(i));
if(_identity.getPublicKeyBlob()==null)
continue;
if(!Util.array_equals(blob, _identity.getPublicKeyBlob())){
continue;
}
if(_identity.isEncrypted()){
if(userinfo==null)
continue;
while(_identity.isEncrypted()){
if(!userinfo.promptPassphrase("Passphrase for "+_identity.getName())){
break;
}
String _passphrase=userinfo.getPassphrase();
if(_passphrase==null){
break;
}
byte[] passphrase=Util.str2byte(_passphrase);
try{
if(_identity.setPassphrase(passphrase)){
break;
}
}
catch(JSchException e){
break;
}
}
}
if(!_identity.isEncrypted()){
identity=_identity;
break;
}
}
}
byte[] signature=null;
if(identity!=null){
signature=identity.getSignature(data);
}
if(signature==null){
mbuf.putByte(SSH2_AGENT_FAILURE);
}
else{
mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE);
mbuf.putString(signature);
}
}
else if(typ==SSH2_AGENTC_REMOVE_IDENTITY){
byte[] blob=rbuf.getString();
irepo.remove(blob);
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES){
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH2_AGENTC_REMOVE_ALL_IDENTITIES){
irepo.removeAll();
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH2_AGENTC_ADD_IDENTITY){
int fooo = rbuf.getLength();
byte[] tmp = new byte[fooo];
rbuf.getByte(tmp);
boolean result = irepo.add(tmp);
mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
}
else {
rbuf.skip(rbuf.getLength()-1);
mbuf.putByte(SSH_AGENT_FAILURE);
}
byte[] response = new byte[mbuf.getLength()];
mbuf.getByte(response);
send(response);
}
private void send(byte[] message){
packet.reset();
wbuf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
wbuf.putInt(recipient);
wbuf.putInt(4+message.length);
wbuf.putString(message);
try{
getSession().write(packet, this, 4+message.length);
}
catch(Exception e){
}
}
void eof_remote(){
super.eof_remote();
eof();
}
}

View File

@ -0,0 +1,161 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
public class ChannelDirectTCPIP extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final byte[] _type = Util.str2byte("direct-tcpip");
String host;
int port;
String originator_IP_address="127.0.0.1";
int originator_port=0;
ChannelDirectTCPIP(){
super();
type = _type;
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
}
void init (){
io=new IO();
}
public void connect(int connectTimeout) throws JSchException{
this.connectTimeout=connectTimeout;
try{
Session _session=getSession();
if(!_session.isConnected()){
throw new JSchException("session is down");
}
if(io.in!=null){
thread=new Thread(this);
thread.setName("DirectTCPIP thread "+_session.getHost());
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
else {
sendChannelOpen();
}
}
catch(Exception e){
io.close();
io=null;
Channel.del(this);
if (e instanceof JSchException) {
throw (JSchException) e;
}
}
}
public void run(){
try{
sendChannelOpen();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
Session _session=getSession();
int i=0;
while(isConnected() &&
thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i<=0){
eof();
break;
}
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized(this){
if(close)
break;
_session.write(packet, this, i);
}
}
}
catch(Exception e){
}
disconnect();
}
public void setInputStream(InputStream in){
io.setInputStream(in);
}
public void setOutputStream(OutputStream out){
io.setOutputStream(out);
}
public void setHost(String host){this.host=host;}
public void setPort(int port){this.port=port;}
public void setOrgIPAddress(String foo){this.originator_IP_address=foo;}
public void setOrgPort(int foo){this.originator_port=foo;}
protected Packet genChannelOpenPacket(){
Buffer buf = new Buffer(50 + // 6 + 4*8 + 12
host.length() + originator_IP_address.length() +
Session.buffer_margin);
Packet packet = new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
// uint32 sender channel // 0
// uint32 initial window size // 0x100000(65536)
// uint32 maxmum packet size // 0x4000(16384)
packet.reset();
buf.putByte((byte)90);
buf.putString(this.type);
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
buf.putString(Util.str2byte(host));
buf.putInt(port);
buf.putString(Util.str2byte(originator_IP_address));
buf.putInt(originator_port);
return packet;
}
}

View File

@ -0,0 +1,83 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.*;
public class ChannelExec extends ChannelSession{
byte[] command=new byte[0];
public void start() throws JSchException{
Session _session=getSession();
try{
sendRequests();
Request request=new RequestExec(command);
request.request(_session, this);
}
catch(Exception e){
if(e instanceof JSchException) throw (JSchException)e;
if(e instanceof Throwable)
throw new JSchException("ChannelExec", (Throwable)e);
throw new JSchException("ChannelExec");
}
if(io.in!=null){
thread=new Thread(this);
thread.setName("Exec thread "+_session.getHost());
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
public void setCommand(String command){
this.command=Util.str2byte(command);
}
public void setCommand(byte[] command){
this.command=command;
}
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(java.io.OutputStream out){
setExtOutputStream(out);
}
public void setErrStream(java.io.OutputStream out, boolean dontclose){
setExtOutputStream(out, dontclose);
}
public java.io.InputStream getErrStream() throws java.io.IOException {
return getExtInputStream();
}
}

View File

@ -0,0 +1,331 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
import java.io.*;
import java.util.Vector;
public class ChannelForwardedTCPIP extends Channel{
private static Vector pool = new Vector();
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final int TIMEOUT=10*1000;
private Socket socket=null;
private ForwardedTCPIPDaemon daemon=null;
private Config config = null;
ChannelForwardedTCPIP(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
io=new IO();
connected=true;
}
public void run(){
try{
if(config instanceof ConfigDaemon){
ConfigDaemon _config = (ConfigDaemon)config;
Class c=Class.forName(_config.target);
daemon=(ForwardedTCPIPDaemon)c.newInstance();
PipedOutputStream out=new PipedOutputStream();
io.setInputStream(new PassiveInputStream(out
, 32*1024
), false);
daemon.setChannel(this, getInputStream(), out);
daemon.setArg(_config.arg);
new Thread(daemon).start();
}
else{
ConfigLHost _config = (ConfigLHost)config;
socket=(_config.factory==null) ?
Util.createSocket(_config.target, _config.lport, TIMEOUT) :
_config.factory.createSocket(_config.target, _config.lport);
socket.setTcpNoDelay(true);
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
}
sendOpenConfirmation();
}
catch(Exception e){
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close=true;
disconnect();
return;
}
thread=Thread.currentThread();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=0;
try{
Session _session = getSession();
while(thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i<=0){
eof();
break;
}
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized(this){
if(close)
break;
_session.write(packet, this, i);
}
}
}
catch(Exception e){
//System.err.println(e);
}
//thread=null;
//eof();
disconnect();
}
void getData(Buffer buf){
setRecipient(buf.getInt());
setRemoteWindowSize(buf.getUInt());
setRemotePacketSize(buf.getInt());
byte[] addr=buf.getString();
int port=buf.getInt();
byte[] orgaddr=buf.getString();
int orgport=buf.getInt();
/*
System.err.println("addr: "+Util.byte2str(addr));
System.err.println("port: "+port);
System.err.println("orgaddr: "+Util.byte2str(orgaddr));
System.err.println("orgport: "+orgport);
*/
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
// session has been already down.
}
this.config = getPort(_session, Util.byte2str(addr), port);
if(this.config == null)
this.config = getPort(_session, null, port);
if(this.config == null){
if(JSch.getLogger().isEnabled(Logger.ERROR)){
JSch.getLogger().log(Logger.ERROR,
"ChannelForwardedTCPIP: "+Util.byte2str(addr)+":"+port+" is not registered.");
}
}
}
private static Config getPort(Session session, String address_to_bind, int rport){
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Config bar = (Config)(pool.elementAt(i));
if(bar.session != session) continue;
if(bar.rport != rport) {
if(bar.rport != 0 || bar.allocated_rport != rport)
continue;
}
if(address_to_bind != null &&
!bar.address_to_bind.equals(address_to_bind)) continue;
return bar;
}
return null;
}
}
static String[] getPortForwarding(Session session){
Vector foo = new Vector();
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Config config = (Config)(pool.elementAt(i));
if(config instanceof ConfigDaemon)
foo.addElement(config.allocated_rport+":"+config.target+":");
else
foo.addElement(config.allocated_rport+":"+config.target+":"+((ConfigLHost)config).lport);
}
}
String[] bar=new String[foo.size()];
for(int i=0; i<foo.size(); i++){
bar[i]=(String)(foo.elementAt(i));
}
return bar;
}
static String normalize(String address){
if(address==null){ return "localhost"; }
else if(address.length()==0 || address.equals("*")){ return ""; }
else{ return address; }
}
static void addPort(Session session, String _address_to_bind,
int port, int allocated_port, String target, int lport, SocketFactory factory) throws JSchException{
String address_to_bind=normalize(_address_to_bind);
synchronized(pool){
if(getPort(session, address_to_bind, port)!=null){
throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
}
ConfigLHost config = new ConfigLHost();
config.session = session;
config.rport = port;
config.allocated_rport = allocated_port;
config.target = target;
config.lport =lport;
config.address_to_bind = address_to_bind;
config.factory = factory;
pool.addElement(config);
}
}
static void addPort(Session session, String _address_to_bind,
int port, int allocated_port, String daemon, Object[] arg) throws JSchException{
String address_to_bind=normalize(_address_to_bind);
synchronized(pool){
if(getPort(session, address_to_bind, port)!=null){
throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
}
ConfigDaemon config = new ConfigDaemon();
config.session = session;
config.rport = port;
config.allocated_rport = port;
config.target = daemon;
config.arg = arg;
config.address_to_bind = address_to_bind;
pool.addElement(config);
}
}
static void delPort(ChannelForwardedTCPIP c){
Session _session=null;
try{
_session=c.getSession();
}
catch(JSchException e){
// session has been already down.
}
if(_session!=null && c.config!=null)
delPort(_session, c.config.rport);
}
static void delPort(Session session, int rport){
delPort(session, null, rport);
}
static void delPort(Session session, String address_to_bind, int rport){
synchronized(pool){
Config foo = getPort(session, normalize(address_to_bind), rport);
if(foo == null)
foo = getPort(session, null, rport);
if(foo==null) return;
pool.removeElement(foo);
if(address_to_bind==null){
address_to_bind=foo.address_to_bind;
}
if(address_to_bind==null){
address_to_bind="0.0.0.0";
}
}
Buffer buf=new Buffer(100); // ??
Packet packet=new Packet(buf);
try{
// byte SSH_MSG_GLOBAL_REQUEST 80
// string "cancel-tcpip-forward"
// boolean want_reply
// string address_to_bind (e.g. "127.0.0.1")
// uint32 port number to bind
packet.reset();
buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
buf.putString(Util.str2byte("cancel-tcpip-forward"));
buf.putByte((byte)0);
buf.putString(Util.str2byte(address_to_bind));
buf.putInt(rport);
session.write(packet);
}
catch(Exception e){
// throw new JSchException(e.toString());
}
}
static void delPort(Session session){
int[] rport=null;
int count=0;
synchronized(pool){
rport=new int[pool.size()];
for(int i=0; i<pool.size(); i++){
Config config = (Config)(pool.elementAt(i));
if(config.session == session) {
rport[count++]=config.rport; // ((Integer)bar[1]).intValue();
}
}
}
for(int i=0; i<count; i++){
delPort(session, rport[i]);
}
}
public int getRemotePort(){return (config!=null ? config.rport: 0);}
private void setSocketFactory(SocketFactory factory){
if(config!=null && (config instanceof ConfigLHost) )
((ConfigLHost)config).factory = factory;
}
static abstract class Config {
Session session;
int rport;
int allocated_rport;
String address_to_bind;
String target;
}
static class ConfigDaemon extends Config {
Object[] arg;
}
static class ConfigLHost extends Config {
int lport;
SocketFactory factory;
}
}

View File

@ -0,0 +1,276 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.*;
class ChannelSession extends Channel{
private static byte[] _session=Util.str2byte("session");
protected boolean agent_forwarding=false;
protected boolean xforwading=false;
protected Hashtable env=null;
protected boolean pty=false;
protected String ttype="vt100";
protected int tcol=80;
protected int trow=24;
protected int twp=640;
protected int thp=480;
protected byte[] terminal_mode=null;
ChannelSession(){
super();
type=_session;
io=new IO();
}
/**
* Enable the agent forwarding.
*
* @param enable
*/
public void setAgentForwarding(boolean enable){
agent_forwarding=enable;
}
/**
* Enable the X11 forwarding.
* Refer to RFC4254 6.3.1. Requesting X11 Forwarding.
*
* @param enable
*/
public void setXForwarding(boolean enable){
xforwading=enable;
}
/**
* @deprecated Use {@link #setEnv(String, String)} or {@link #setEnv(byte[], byte[])} instead.
* @see #setEnv(String, String)
* @see #setEnv(byte[], byte[])
*/
public void setEnv(Hashtable env){
synchronized(this){
this.env=env;
}
}
/**
* Set the environment variable.
* If <code>name</code> and <code>value</code> are needed to be passed
* to the remote in your favorite encoding,
* use {@link #setEnv(byte[], byte[])}.
* Refer to RFC4254 6.4 Environment Variable Passing.
*
* @param name A name for environment variable.
* @param value A value for environment variable.
*/
public void setEnv(String name, String value){
setEnv(Util.str2byte(name), Util.str2byte(value));
}
/**
* Set the environment variable.
* Refer to RFC4254 6.4 Environment Variable Passing.
*
* @param name A name of environment variable.
* @param value A value of environment variable.
* @see #setEnv(String, String)
*/
public void setEnv(byte[] name, byte[] value){
synchronized(this){
getEnv().put(name, value);
}
}
private Hashtable getEnv(){
if(env==null)
env=new Hashtable();
return env;
}
/**
* Allocate a Pseudo-Terminal.
* Refer to RFC4254 6.2. Requesting a Pseudo-Terminal.
*
* @param enable
*/
public void setPty(boolean enable){
pty=enable;
}
/**
* Set the terminal mode.
*
* @param terminal_mode
*/
public void setTerminalMode(byte[] terminal_mode){
this.terminal_mode=terminal_mode;
}
/**
* Change the window dimension interactively.
* Refer to RFC4254 6.7. Window Dimension Change Message.
*
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtySize(int col, int row, int wp, int hp){
setPtyType(this.ttype, col, row, wp, hp);
if(!pty || !isConnected()){
return;
}
try{
RequestWindowChange request=new RequestWindowChange();
request.setSize(col, row, wp, hp);
request.request(getSession(), this);
}
catch(Exception e){
//System.err.println("ChannelSessio.setPtySize: "+e);
}
}
/**
* Set the terminal type.
* This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @see #setPtyType(String, int, int, int, int)
*/
public void setPtyType(String ttype){
setPtyType(ttype, 80, 24, 640, 480);
}
/**
* Set the terminal type.
* This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtyType(String ttype, int col, int row, int wp, int hp){
this.ttype=ttype;
this.tcol=col;
this.trow=row;
this.twp=wp;
this.thp=hp;
}
protected void sendRequests() throws Exception{
Session _session=getSession();
Request request;
if(agent_forwarding){
request=new RequestAgentForwarding();
request.request(_session, this);
}
if(xforwading){
request=new RequestX11();
request.request(_session, this);
}
if(pty){
request=new RequestPtyReq();
((RequestPtyReq)request).setTType(ttype);
((RequestPtyReq)request).setTSize(tcol, trow, twp, thp);
if(terminal_mode!=null){
((RequestPtyReq)request).setTerminalMode(terminal_mode);
}
request.request(_session, this);
}
if(env!=null){
for(Enumeration _env=env.keys(); _env.hasMoreElements();){
Object name=_env.nextElement();
Object value=env.get(name);
request=new RequestEnv();
((RequestEnv)request).setEnv(toByteArray(name),
toByteArray(value));
request.request(_session, this);
}
}
}
private byte[] toByteArray(Object o){
if(o instanceof String){
return Util.str2byte((String)o);
}
return (byte[])o;
}
public void run(){
//System.err.println(this+":run >");
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=-1;
try{
while(isConnected() &&
thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i==0)continue;
if(i==-1){
eof();
break;
}
if(close)break;
//System.out.println("write: "+i);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
}
}
catch(Exception e){
//System.err.println("# ChannelExec.run");
//e.printStackTrace();
}
Thread _thread=thread;
if(_thread!=null){
synchronized(_thread){ _thread.notifyAll(); }
}
thread=null;
//System.err.println(this+":run <");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.*;
public class ChannelShell extends ChannelSession{
ChannelShell(){
super();
pty=true;
}
public void start() throws JSchException{
Session _session=getSession();
try{
sendRequests();
Request request=new RequestShell();
request.request(_session, this);
}
catch(Exception e){
if(e instanceof JSchException) throw (JSchException)e;
if(e instanceof Throwable)
throw new JSchException("ChannelShell", (Throwable)e);
throw new JSchException("ChannelShell");
}
if(io.in!=null){
thread=new Thread(this);
thread.setName("Shell for "+_session.host);
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
}

View File

@ -0,0 +1,83 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class ChannelSubsystem extends ChannelSession{
boolean xforwading=false;
boolean pty=false;
boolean want_reply=true;
String subsystem="";
public void setXForwarding(boolean foo){ xforwading=foo; }
public void setPty(boolean foo){ pty=foo; }
public void setWantReply(boolean foo){ want_reply=foo; }
public void setSubsystem(String foo){ subsystem=foo; }
public void start() throws JSchException{
Session _session=getSession();
try{
Request request;
if(xforwading){
request=new RequestX11();
request.request(_session, this);
}
if(pty){
request=new RequestPtyReq();
request.request(_session, this);
}
request=new RequestSubsystem();
((RequestSubsystem)request).request(_session, this, subsystem, want_reply);
}
catch(Exception e){
if(e instanceof JSchException){ throw (JSchException)e; }
if(e instanceof Throwable)
throw new JSchException("ChannelSubsystem", (Throwable)e);
throw new JSchException("ChannelSubsystem");
}
if(io.in!=null){
thread=new Thread(this);
thread.setName("Subsystem for "+_session.host);
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(java.io.OutputStream out){
setExtOutputStream(out);
}
public java.io.InputStream getErrStream() throws java.io.IOException {
return getExtInputStream();
}
}

View File

@ -0,0 +1,273 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
class ChannelX11 extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final int TIMEOUT=10*1000;
private static String host="127.0.0.1";
private static int port=6000;
private boolean init=true;
static byte[] cookie=null;
private static byte[] cookie_hex=null;
private static java.util.Hashtable faked_cookie_pool=new java.util.Hashtable();
private static java.util.Hashtable faked_cookie_hex_pool=new java.util.Hashtable();
private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x61,0x62,0x63,0x64,0x65,0x66};
private Socket socket = null;
static int revtable(byte foo){
for(int i=0; i<table.length; i++){
if(table[i]==foo)return i;
}
return 0;
}
static void setCookie(String foo){
cookie_hex=Util.str2byte(foo);
cookie=new byte[16];
for(int i=0; i<16; i++){
cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
((revtable(cookie_hex[i*2+1]))&0xf));
}
}
static void setHost(String foo){ host=foo; }
static void setPort(int foo){ port=foo; }
static byte[] getFakedCookie(Session session){
synchronized(faked_cookie_hex_pool){
byte[] foo=(byte[])faked_cookie_hex_pool.get(session);
if(foo==null){
Random random=Session.random;
foo=new byte[16];
synchronized(random){
random.fill(foo, 0, 16);
}
/*
System.err.print("faked_cookie: ");
for(int i=0; i<foo.length; i++){
System.err.print(Integer.toHexString(foo[i]&0xff)+":");
}
System.err.println("");
*/
faked_cookie_pool.put(session, foo);
byte[] bar=new byte[32];
for(int i=0; i<16; i++){
bar[2*i]=table[(foo[i]>>>4)&0xf];
bar[2*i+1]=table[(foo[i])&0xf];
}
faked_cookie_hex_pool.put(session, bar);
foo=bar;
}
return foo;
}
}
static void removeFakedCookie(Session session){
synchronized(faked_cookie_hex_pool){
faked_cookie_hex_pool.remove(session);
faked_cookie_pool.remove(session);
}
}
ChannelX11(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
type=Util.str2byte("x11");
connected=true;
/*
try{
socket=Util.createSocket(host, port, TIMEOUT);
socket.setTcpNoDelay(true);
io=new IO();
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
}
catch(Exception e){
//System.err.println(e);
}
*/
}
public void run(){
try{
socket=Util.createSocket(host, port, TIMEOUT);
socket.setTcpNoDelay(true);
io=new IO();
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
sendOpenConfirmation();
}
catch(Exception e){
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close=true;
disconnect();
return;
}
thread=Thread.currentThread();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=0;
try{
while(thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14-Session.buffer_margin);
if(i<=0){
eof();
break;
}
if(close)break;
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
}
}
catch(Exception e){
//System.err.println(e);
}
disconnect();
}
private byte[] cache=new byte[0];
private byte[] addCache(byte[] foo, int s, int l){
byte[] bar=new byte[cache.length+l];
System.arraycopy(foo, s, bar, cache.length, l);
if(cache.length>0)
System.arraycopy(cache, 0, bar, 0, cache.length);
cache=bar;
return cache;
}
void write(byte[] foo, int s, int l) throws java.io.IOException {
//if(eof_local)return;
if(init){
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
throw new java.io.IOException(e.toString());
}
foo=addCache(foo, s, l);
s=0;
l=foo.length;
if(l<9)
return;
int plen=(foo[s+6]&0xff)*256+(foo[s+7]&0xff);
int dlen=(foo[s+8]&0xff)*256+(foo[s+9]&0xff);
if((foo[s]&0xff)==0x42){
}
else if((foo[s]&0xff)==0x6c){
plen=((plen>>>8)&0xff)|((plen<<8)&0xff00);
dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00);
}
else{
// ??
}
if(l<12+plen+((-plen)&3)+dlen)
return;
byte[] bar=new byte[dlen];
System.arraycopy(foo, s+12+plen+((-plen)&3), bar, 0, dlen);
byte[] faked_cookie=null;
synchronized(faked_cookie_pool){
faked_cookie=(byte[])faked_cookie_pool.get(_session);
}
/*
System.err.print("faked_cookie: ");
for(int i=0; i<faked_cookie.length; i++){
System.err.print(Integer.toHexString(faked_cookie[i]&0xff)+":");
}
System.err.println("");
System.err.print("bar: ");
for(int i=0; i<bar.length; i++){
System.err.print(Integer.toHexString(bar[i]&0xff)+":");
}
System.err.println("");
*/
if(equals(bar, faked_cookie)){
if(cookie!=null)
System.arraycopy(cookie, 0, foo, s+12+plen+((-plen)&3), dlen);
}
else{
//System.err.println("wrong cookie");
thread=null;
eof();
io.close();
disconnect();
}
init=false;
io.put(foo, s, l);
cache=null;
return;
}
io.put(foo, s, l);
}
private static boolean equals(byte[] foo, byte[] bar){
if(foo.length!=bar.length)return false;
for(int i=0; i<foo.length; i++){
if(foo[i]!=bar[i])return false;
}
return true;
}
}

View File

@ -0,0 +1,40 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Cipher{
static int ENCRYPT_MODE=0;
static int DECRYPT_MODE=1;
int getIVSize();
int getBlockSize();
void init(int mode, byte[] key, byte[] iv) throws Exception;
void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
boolean isCBC();
}

View File

@ -0,0 +1,42 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class CipherNone implements Cipher{
private static final int ivsize=8;
private static final int bsize=16;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,38 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Compression{
static public final int INFLATER=0;
static public final int DEFLATER=1;
void init(int type, int level);
byte[] compress(byte[] buf, int start, int[] len);
byte[] uncompress(byte[] buf, int start, int[] len);
}

View File

@ -0,0 +1,55 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2013 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface ConfigRepository {
public Config getConfig(String host);
public interface Config {
public String getHostname();
public String getUser();
public int getPort();
public String getValue(String key);
public String[] getValues(String key);
}
static final Config defaultConfig = new Config() {
public String getHostname() {return null;}
public String getUser() {return null;}
public int getPort() {return -1;}
public String getValue(String key) {return null;}
public String[] getValues(String key) {return null;}
};
static final ConfigRepository nullConfig = new ConfigRepository(){
public Config getConfig(String host) { return defaultConfig; }
};
}

View File

@ -0,0 +1,39 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface DH{
void init() throws Exception;
void setP(byte[] p);
void setG(byte[] g);
byte[] getE() throws Exception;
void setF(byte[] f);
byte[] getK() throws Exception;
}

View File

@ -0,0 +1,310 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class DHG1 extends KeyExchange{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
private static final int SSH_MSG_KEXDH_INIT= 30;
private static final int SSH_MSG_KEXDH_REPLY= 31;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state;
DH dh;
// HASH sha;
// byte[] K;
// byte[] H;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
// byte[] K_S;
byte[] e;
private Buffer buf;
private Packet packet;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
// sha=new SHA1();
// sha.init();
try{
Class c=Class.forName(session.getConfig("sha-1"));
sha=(HASH)(c.newInstance());
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class c=Class.forName(session.getConfig("dh"));
dh=(DH)(c.newInstance());
dh.init();
}
catch(Exception e){
//System.err.println(e);
throw e;
}
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEXDH_INIT(30)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEXDH_INIT);
buf.putMPInt(e);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEXDH_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEXDH_REPLY");
}
state=SSH_MSG_KEXDH_REPLY;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEXDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEXDH_REPLY(31)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=31){
System.err.println("type: must be 31 "+j);
return false;
}
K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
/*
for(int ii=0; ii<sig_of_H.length;ii++){
System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
System.err.print(": ");
}
System.err.println("");
*/
dh.setF(f);
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
//System.err.print("H -> "); //dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
byte[] p;
byte[] g;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END;
return result;
}
return false;
}
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; }
}

View File

@ -0,0 +1,310 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class DHG14 extends KeyExchange{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
private static final int SSH_MSG_KEXDH_INIT= 30;
private static final int SSH_MSG_KEXDH_REPLY= 31;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class c=Class.forName(session.getConfig("sha-1"));
sha=(HASH)(c.newInstance());
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class c=Class.forName(session.getConfig("dh"));
dh=(DH)(c.newInstance());
dh.init();
}
catch(Exception e){
//System.err.println(e);
throw e;
}
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEXDH_INIT(30)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEXDH_INIT);
buf.putMPInt(e);
if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEXDH_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEXDH_REPLY");
}
state=SSH_MSG_KEXDH_REPLY;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEXDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEXDH_REPLY(31)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=31){
System.err.println("type: must be 31 "+j);
return false;
}
K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
//System.err.print("H -> "); //dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
byte[] p;
byte[] g;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END;
return result;
}
return false;
}
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; }
}

View File

@ -0,0 +1,340 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class DHGEX extends KeyExchange{
private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31;
private static final int SSH_MSG_KEX_DH_GEX_INIT= 32;
private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33;
private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
static int min=1024;
// static int min=512;
static int preferred=1024;
static int max=1024;
// static int preferred=1024;
// static int max=2000;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state;
// com.jcraft.jsch.DH dh;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
private Buffer buf;
private Packet packet;
private byte[] p;
private byte[] g;
private byte[] e;
//private byte[] f;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class c=Class.forName(session.getConfig("sha-1"));
sha=(HASH)(c.newInstance());
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class c=Class.forName(session.getConfig("dh"));
dh=(com.jcraft.jsch.DH)(c.newInstance());
dh.init();
}
catch(Exception e){
// System.err.println(e);
throw e;
}
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_GROUP");
}
state=SSH_MSG_KEX_DH_GEX_GROUP;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_DH_GEX_GROUP:
// byte SSH_MSG_KEX_DH_GEX_GROUP(31)
// mpint p, safe prime
// mpint g, generator for subgroup in GF (p)
_buf.getInt();
_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
return false;
}
p=_buf.getMPInt();
g=_buf.getMPInt();
/*
for(int iii=0; iii<p.length; iii++){
System.err.println("0x"+Integer.toHexString(p[iii]&0xff)+",");
}
System.err.println("");
for(int iii=0; iii<g.length; iii++){
System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
}
*/
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
buf.putMPInt(e);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_REPLY");
}
state=SSH_MSG_KEX_DH_GEX_REPLY;
return true;
//break;
case SSH_MSG_KEX_DH_GEX_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_DH_GEX_REPLY(33)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
return false;
}
K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// uint32 min, minimal size in bits of an acceptable group
// uint32 n, preferred size in bits of the group the server should send
// uint32 max, maximal size in bits of an acceptable group
// mpint p, safe prime
// mpint g, generator for subgroup
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
// System.err.print("H -> "); dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END;
return result;
}
return false;
}
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; }
}

View File

@ -0,0 +1,340 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class DHGEX256 extends KeyExchange{
private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31;
private static final int SSH_MSG_KEX_DH_GEX_INIT= 32;
private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33;
private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
static int min=1024;
// static int min=512;
static int preferred=1024;
static int max=1024;
// static int preferred=1024;
// static int max=2000;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state;
// com.jcraft.jsch.DH dh;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
private Buffer buf;
private Packet packet;
private byte[] p;
private byte[] g;
private byte[] e;
//private byte[] f;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class c=Class.forName(session.getConfig("sha-256"));
sha=(HASH)(c.newInstance());
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class c=Class.forName(session.getConfig("dh"));
dh=(com.jcraft.jsch.DH)(c.newInstance());
dh.init();
}
catch(Exception e){
// System.err.println(e);
throw e;
}
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_GROUP");
}
state=SSH_MSG_KEX_DH_GEX_GROUP;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_DH_GEX_GROUP:
// byte SSH_MSG_KEX_DH_GEX_GROUP(31)
// mpint p, safe prime
// mpint g, generator for subgroup in GF (p)
_buf.getInt();
_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
return false;
}
p=_buf.getMPInt();
g=_buf.getMPInt();
/*
for(int iii=0; iii<p.length; iii++){
System.err.println("0x"+Integer.toHexString(p[iii]&0xff)+",");
}
System.err.println("");
for(int iii=0; iii<g.length; iii++){
System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
}
*/
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
buf.putMPInt(e);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_REPLY");
}
state=SSH_MSG_KEX_DH_GEX_REPLY;
return true;
//break;
case SSH_MSG_KEX_DH_GEX_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_DH_GEX_REPLY(33)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
return false;
}
K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// uint32 min, minimal size in bits of an acceptable group
// uint32 n, preferred size in bits of the group the server should send
// uint32 max, maximal size in bits of an acceptable group
// mpint p, safe prime
// mpint g, generator for subgroup
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
// System.err.print("H -> "); dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END;
return result;
}
return false;
}
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; }
}

View File

@ -0,0 +1,36 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
public interface ForwardedTCPIPDaemon extends Runnable{
void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out);
void setArg(Object[] arg);
}

View File

@ -0,0 +1,38 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface GSSContext{
public void create(String user, String host) throws JSchException;
public boolean isEstablished();
public byte[] init(byte[] token, int s, int l) throws JSchException;
public byte[] getMIC(byte[] message, int s, int l);
public void dispose();
}

View File

@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface HASH{
void init() throws Exception;
int getBlockSize();
void update(byte[] foo, int start, int len) throws Exception;
byte[] digest() throws Exception;
}

View File

@ -0,0 +1,116 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class HostKey{
private static final byte[] sshdss=Util.str2byte("ssh-dss");
private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
protected static final int GUESS=0;
public static final int SSHDSS=1;
public static final int SSHRSA=2;
static final int UNKNOWN=3;
protected String marker;
protected String host;
protected int type;
protected byte[] key;
protected String comment;
public HostKey(String host, byte[] key) throws JSchException {
this(host, GUESS, key);
}
public HostKey(String host, int type, byte[] key) throws JSchException {
this(host, type, key, null);
}
public HostKey(String host, int type, byte[] key, String comment) throws JSchException {
this("", host, type, key, comment);
}
public HostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException {
this.marker=marker;
this.host=host;
if(type==GUESS){
if(key[8]=='d'){ this.type=SSHDSS; }
else if(key[8]=='r'){ this.type=SSHRSA; }
else { throw new JSchException("invalid key type");}
}
else{
this.type=type;
}
this.key=key;
this.comment=comment;
}
public String getHost(){ return host; }
public String getType(){
if(type==SSHDSS){ return Util.byte2str(sshdss); }
if(type==SSHRSA){ return Util.byte2str(sshrsa);}
return "UNKNOWN";
}
public String getKey(){
return Util.byte2str(Util.toBase64(key, 0, key.length));
}
public String getFingerPrint(JSch jsch){
HASH hash=null;
try{
Class c=Class.forName(jsch.getConfig("md5"));
hash=(HASH)(c.newInstance());
}
catch(Exception e){ System.err.println("getFingerPrint: "+e); }
return Util.getFingerPrint(hash, key);
}
public String getComment(){ return comment; }
public String getMarker(){ return marker; }
boolean isMatched(String _host){
return isIncluded(_host);
}
private boolean isIncluded(String _host){
int i=0;
String hosts=this.host;
int hostslen=hosts.length();
int hostlen=_host.length();
int j;
while(i<hostslen){
j=hosts.indexOf(',', i);
if(j==-1){
if(hostlen!=hostslen-i) return false;
return hosts.regionMatches(true, i, _host, 0, hostlen);
}
if(hostlen==(j-i)){
if(hosts.regionMatches(true, i, _host, 0, hostlen)) return true;
}
i=j+1;
}
return false;
}
}

View File

@ -0,0 +1,44 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface HostKeyRepository{
final int OK=0;
final int NOT_INCLUDED=1;
final int CHANGED=2;
int check(String host, byte[] key);
void add(HostKey hostkey, UserInfo ui);
void remove(String host, String type);
void remove(String host, String type, byte[] key);
String getKnownHostsRepositoryID();
HostKey[] getHostKey();
HostKey[] getHostKey(String host, String type);
}

View File

@ -0,0 +1,132 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
public class IO{
InputStream in;
OutputStream out;
OutputStream out_ext;
private boolean in_dontclose=false;
private boolean out_dontclose=false;
private boolean out_ext_dontclose=false;
void setOutputStream(OutputStream out){ this.out=out; }
void setOutputStream(OutputStream out, boolean dontclose){
this.out_dontclose=dontclose;
setOutputStream(out);
}
void setExtOutputStream(OutputStream out){ this.out_ext=out; }
void setExtOutputStream(OutputStream out, boolean dontclose){
this.out_ext_dontclose=dontclose;
setExtOutputStream(out);
}
void setInputStream(InputStream in){ this.in=in; }
void setInputStream(InputStream in, boolean dontclose){
this.in_dontclose=dontclose;
setInputStream(in);
}
public void put(Packet p) throws IOException, java.net.SocketException {
out.write(p.buffer.buffer, 0, p.buffer.index);
out.flush();
}
void put(byte[] array, int begin, int length) throws IOException {
out.write(array, begin, length);
out.flush();
}
void put_ext(byte[] array, int begin, int length) throws IOException {
out_ext.write(array, begin, length);
out_ext.flush();
}
int getByte() throws IOException {
return in.read();
}
void getByte(byte[] array) throws IOException {
getByte(array, 0, array.length);
}
void getByte(byte[] array, int begin, int length) throws IOException {
do{
int completed = in.read(array, begin, length);
if(completed<0){
throw new IOException("End of IO Stream Read");
}
begin+=completed;
length-=completed;
}
while (length>0);
}
void out_close(){
try{
if(out!=null && !out_dontclose) out.close();
out=null;
}
catch(Exception ee){}
}
public void close(){
try{
if(in!=null && !in_dontclose) in.close();
in=null;
}
catch(Exception ee){}
out_close();
try{
if(out_ext!=null && !out_ext_dontclose) out_ext.close();
out_ext=null;
}
catch(Exception ee){}
}
/*
public void finalize() throws Throwable{
try{
if(in!=null) in.close();
}
catch(Exception ee){}
try{
if(out!=null) out.close();
}
catch(Exception ee){}
try{
if(out_ext!=null) out_ext.close();
}
catch(Exception ee){}
}
*/
}

View File

@ -0,0 +1,83 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Identity{
/**
* Decrypts this identity with the specified pass-phrase.
* @param passphrase the pass-phrase for this identity.
* @return <tt>true</tt> if the decryption is succeeded
* or this identity is not cyphered.
*/
public boolean setPassphrase(byte[] passphrase) throws JSchException;
/**
* Returns the public-key blob.
* @return the public-key blob
*/
public byte[] getPublicKeyBlob();
/**
* Signs on data with this identity, and returns the result.
* @param data data to be signed
* @return the signature
*/
public byte[] getSignature(byte[] data);
/**
* @deprecated The decryption should be done automatically in #setPassphase(byte[] passphrase)
* @see #setPassphrase(byte[] passphrase)
*/
public boolean decrypt();
/**
* Returns the name of the key algorithm.
* @return "ssh-rsa" or "ssh-dss"
*/
public String getAlgName();
/**
* Returns the name of this identity.
* It will be useful to identify this object in the {@link IdentityRepository}.
*/
public String getName();
/**
* Returns <tt>true</tt> if this identity is cyphered.
* @return <tt>true</tt> if this identity is cyphered.
*/
public boolean isEncrypted();
/**
* Disposes internally allocated data, like byte array for the private key.
*/
public void clear();
}

View File

@ -0,0 +1,129 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
class IdentityFile implements Identity{
private JSch jsch;
private KeyPair kpair;
private String identity;
static IdentityFile newInstance(String prvfile, String pubfile, JSch jsch) throws JSchException{
KeyPair kpair = KeyPair.load(jsch, prvfile, pubfile);
return new IdentityFile(jsch, prvfile, kpair);
}
static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey);
return new IdentityFile(jsch, name, kpair);
}
private IdentityFile(JSch jsch, String name, KeyPair kpair) throws JSchException{
this.jsch = jsch;
this.identity = name;
this.kpair = kpair;
}
/**
* Decrypts this identity with the specified pass-phrase.
* @param passphrase the pass-phrase for this identity.
* @return <tt>true</tt> if the decryption is succeeded
* or this identity is not cyphered.
*/
public boolean setPassphrase(byte[] passphrase) throws JSchException{
return kpair.decrypt(passphrase);
}
/**
* Returns the public-key blob.
* @return the public-key blob
*/
public byte[] getPublicKeyBlob(){
return kpair.getPublicKeyBlob();
}
/**
* Signs on data with this identity, and returns the result.
* @param data data to be signed
* @return the signature
*/
public byte[] getSignature(byte[] data){
return kpair.getSignature(data);
}
/**
* @deprecated This method should not be invoked.
* @see #setPassphrase(byte[] passphrase)
*/
public boolean decrypt(){
throw new RuntimeException("not implemented");
}
/**
* Returns the name of the key algorithm.
* @return "ssh-rsa" or "ssh-dss"
*/
public String getAlgName(){
return new String(kpair.getKeyTypeName());
}
/**
* Returns the name of this identity.
* It will be useful to identify this object in the {@link IdentityRepository}.
*/
public String getName(){
return identity;
}
/**
* Returns <tt>true</tt> if this identity is cyphered.
* @return <tt>true</tt> if this identity is cyphered.
*/
public boolean isEncrypted(){
return kpair.isEncrypted();
}
/**
* Disposes internally allocated data, like byte array for the private key.
*/
public void clear(){
kpair.dispose();
kpair = null;
}
/**
* Returns an instance of {@link KeyPair} used in this {@link Identity}.
* @return an instance of {@link KeyPair} used in this {@link Identity}.
*/
public KeyPair getKeyPair(){
return kpair;
}
}

View File

@ -0,0 +1,115 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
public interface IdentityRepository {
public static final int UNAVAILABLE=0;
public static final int NOTRUNNING=1;
public static final int RUNNING=2;
public String getName();
public int getStatus();
public Vector getIdentities();
public boolean add(byte[] identity);
public boolean remove(byte[] blob);
public void removeAll();
/**
* JSch will accept ciphered keys, but some implementations of
* IdentityRepository can not. For example, IdentityRepository for
* ssh-agent and pageant only accept plain keys. The following class has
* been introduced to cache ciphered keys for them, and pass them
* whenever they are de-ciphered.
*/
static class Wrapper implements IdentityRepository {
private IdentityRepository ir;
private Vector cache = new Vector();
private boolean keep_in_cache = false;
Wrapper(IdentityRepository ir){
this(ir, false);
}
Wrapper(IdentityRepository ir, boolean keep_in_cache){
this.ir = ir;
this.keep_in_cache = keep_in_cache;
}
public String getName() {
return ir.getName();
}
public int getStatus() {
return ir.getStatus();
}
public boolean add(byte[] identity) {
return ir.add(identity);
}
public boolean remove(byte[] blob) {
return ir.remove(blob);
}
public void removeAll() {
cache.removeAllElements();
ir.removeAll();
}
public Vector getIdentities() {
Vector result = new Vector();
for(int i = 0; i< cache.size(); i++){
Identity identity = (Identity)(cache.elementAt(i));
result.add(identity);
}
Vector tmp = ir.getIdentities();
for(int i = 0; i< tmp.size(); i++){
result.add(tmp.elementAt(i));
}
return result;
}
void add(Identity identity) {
if(!keep_in_cache &&
!identity.isEncrypted() && (identity instanceof IdentityFile)) {
try {
ir.add(((IdentityFile)identity).getKeyPair().forSSHAgent());
}
catch(JSchException e){
// an exception will not be thrown.
}
}
else
cache.addElement(identity);
}
void check() {
if(cache.size() > 0){
Object[] identities = cache.toArray();
for(int i = 0; i < identities.length; i++){
Identity identity = (Identity)(identities[i]);
cache.removeElement(identity);
add(identity);
}
}
}
}
}

View File

@ -0,0 +1,573 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.InputStream;
import java.util.Vector;
public class JSch{
/**
* The version number.
*/
public static final String VERSION = "0.1.50";
static java.util.Hashtable config=new java.util.Hashtable();
static{
config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1");
config.put("server_host_key", "ssh-rsa,ssh-dss");
config.put("cipher.s2c",
"aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc");
config.put("cipher.c2s",
"aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc");
config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96");
config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96");
config.put("compression.s2c", "none");
config.put("compression.c2s", "none");
config.put("lang.s2c", "");
config.put("lang.c2s", "");
config.put("compression_level", "6");
config.put("diffie-hellman-group-exchange-sha1",
"com.jcraft.jsch.DHGEX");
config.put("diffie-hellman-group1-sha1",
"com.jcraft.jsch.DHG1");
config.put("diffie-hellman-group14-sha1",
"com.jcraft.jsch.DHG14");
config.put("diffie-hellman-group-exchange-sha256",
"com.jcraft.jsch.DHGEX256"); // avaibale since JDK1.4.2.
config.put("dh", "com.jcraft.jsch.jce.DH");
config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC");
config.put("blowfish-cbc", "com.jcraft.jsch.jce.BlowfishCBC");
config.put("hmac-sha1", "com.jcraft.jsch.jce.HMACSHA1");
config.put("hmac-sha1-96", "com.jcraft.jsch.jce.HMACSHA196");
config.put("hmac-sha2-256", "com.jcraft.jsch.jce.HMACSHA256");
// The "hmac-sha2-512" will require the key-length 2048 for DH,
// but Sun's JCE has not allowed to use such a long key.
//config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512");
config.put("hmac-md5", "com.jcraft.jsch.jce.HMACMD5");
config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596");
config.put("sha-1", "com.jcraft.jsch.jce.SHA1");
config.put("sha-256", "com.jcraft.jsch.jce.SHA256");
config.put("md5", "com.jcraft.jsch.jce.MD5");
config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA");
config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA");
config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA");
config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA");
config.put("random", "com.jcraft.jsch.jce.Random");
config.put("none", "com.jcraft.jsch.CipherNone");
config.put("aes128-cbc", "com.jcraft.jsch.jce.AES128CBC");
config.put("aes192-cbc", "com.jcraft.jsch.jce.AES192CBC");
config.put("aes256-cbc", "com.jcraft.jsch.jce.AES256CBC");
config.put("aes128-ctr", "com.jcraft.jsch.jce.AES128CTR");
config.put("aes192-ctr", "com.jcraft.jsch.jce.AES192CTR");
config.put("aes256-ctr", "com.jcraft.jsch.jce.AES256CTR");
config.put("3des-ctr", "com.jcraft.jsch.jce.TripleDESCTR");
config.put("arcfour", "com.jcraft.jsch.jce.ARCFOUR");
config.put("arcfour128", "com.jcraft.jsch.jce.ARCFOUR128");
config.put("arcfour256", "com.jcraft.jsch.jce.ARCFOUR256");
config.put("userauth.none", "com.jcraft.jsch.UserAuthNone");
config.put("userauth.password", "com.jcraft.jsch.UserAuthPassword");
config.put("userauth.keyboard-interactive", "com.jcraft.jsch.UserAuthKeyboardInteractive");
config.put("userauth.publickey", "com.jcraft.jsch.UserAuthPublicKey");
config.put("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMIC");
config.put("gssapi-with-mic.krb5", "com.jcraft.jsch.jgss.GSSContextKrb5");
config.put("zlib", "com.jcraft.jsch.jcraft.Compression");
config.put("zlib@openssh.com", "com.jcraft.jsch.jcraft.Compression");
config.put("StrictHostKeyChecking", "ask");
config.put("HashKnownHosts", "no");
config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
config.put("CheckCiphers", "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256");
config.put("CheckKexes", "diffie-hellman-group14-sha1");
config.put("MaxAuthTries", "6");
config.put("ClearAllForwardings", "no");
}
private java.util.Vector sessionPool = new java.util.Vector();
private IdentityRepository defaultIdentityRepository =
new LocalIdentityRepository(this);
private IdentityRepository identityRepository = defaultIdentityRepository;
private ConfigRepository configRepository = null;
/**
* Sets the <code>identityRepository</code>, which will be referred
* in the public key authentication.
*
* @param identityRepository if <code>null</code> is given,
* the default repository, which usually refers to ~/.ssh/, will be used.
*
* @see #getIdentityRepository()
*/
public synchronized void setIdentityRepository(IdentityRepository identityRepository){
if(identityRepository == null){
this.identityRepository = defaultIdentityRepository;
}
else{
this.identityRepository = identityRepository;
}
}
public synchronized IdentityRepository getIdentityRepository(){
return this.identityRepository;
}
public ConfigRepository getConfigRepository() {
return this.configRepository;
}
public void setConfigRepository(ConfigRepository configRepository) {
this.configRepository = configRepository;
}
private HostKeyRepository known_hosts=null;
private static final Logger DEVNULL=new Logger(){
public boolean isEnabled(int level){return false;}
public void log(int level, String message){}
};
static Logger logger=DEVNULL;
public JSch(){
try{
String osname=(String)(System.getProperties().get("os.name"));
if(osname!=null && osname.equals("Mac OS X")){
config.put("hmac-sha1", "com.jcraft.jsch.jcraft.HMACSHA1");
config.put("hmac-md5", "com.jcraft.jsch.jcraft.HMACMD5");
config.put("hmac-md5-96", "com.jcraft.jsch.jcraft.HMACMD596");
config.put("hmac-sha1-96", "com.jcraft.jsch.jcraft.HMACSHA196");
}
}
catch(Exception e){
}
}
/**
* Instantiates the <code>Session</code> object with
* <code>host</code>. The user name and port number will be retrieved from
* ConfigRepository. If user name is not given,
* the system property "user.name" will be referred.
*
* @param host hostname
*
* @throws JSchException
* if <code>username</code> or <code>host</code> are invalid.
*
* @return the instance of <code>Session</code> class.
*
* @see #getSession(String username, String host, int port)
* @see com.jcraft.jsch.Session
* @see com.jcraft.jsch.ConfigRepository
*/
public Session getSession(String host)
throws JSchException {
return getSession(null, host, 22);
}
/**
* Instantiates the <code>Session</code> object with
* <code>username</code> and <code>host</code>.
* The TCP port 22 will be used in making the connection.
* Note that the TCP connection must not be established
* until Session#connect().
*
* @param username user name
* @param host hostname
*
* @throws JSchException
* if <code>username</code> or <code>host</code> are invalid.
*
* @return the instance of <code>Session</code> class.
*
* @see #getSession(String username, String host, int port)
* @see com.jcraft.jsch.Session
*/
public Session getSession(String username, String host)
throws JSchException {
return getSession(username, host, 22);
}
/**
* Instantiates the <code>Session</code> object with given
* <code>username</code>, <code>host</code> and <code>port</code>.
* Note that the TCP connection must not be established
* until Session#connect().
*
* @param username user name
* @param host hostname
* @param port port number
*
* @throws JSchException
* if <code>username</code> or <code>host</code> are invalid.
*
* @return the instance of <code>Session</code> class.
*
* @see #getSession(String username, String host, int port)
* @see com.jcraft.jsch.Session
*/
public Session getSession(String username, String host, int port) throws JSchException {
if(host==null){
throw new JSchException("host must not be null.");
}
Session s = new Session(this, username, host, port);
return s;
}
protected void addSession(Session session){
synchronized(sessionPool){
sessionPool.addElement(session);
}
}
protected boolean removeSession(Session session){
synchronized(sessionPool){
return sessionPool.remove(session);
}
}
/**
* Sets the hostkey repository.
*
* @param hkrepo
*
* @see com.jcraft.jsch.HostKeyRepository
* @see com.jcraft.jsch.KnownHosts
*/
public void setHostKeyRepository(HostKeyRepository hkrepo){
known_hosts=hkrepo;
}
/**
* Sets the instance of <code>KnownHosts</code>, which refers
* to <code>filename</code>.
*
* @param filename filename of known_hosts file.
*
* @throws JSchException
* if the given filename is invalid.
*
* @see com.jcraft.jsch.KnownHosts
*/
public void setKnownHosts(String filename) throws JSchException{
if(known_hosts==null) known_hosts=new KnownHosts(this);
if(known_hosts instanceof KnownHosts){
synchronized(known_hosts){
((KnownHosts)known_hosts).setKnownHosts(filename);
}
}
}
/**
* Sets the instance of <code>KnownHosts</code> generated with
* <code>stream</code>.
*
* @param stream the instance of InputStream from known_hosts file.
*
* @throws JSchException
* if an I/O error occurs.
*
* @see com.jcraft.jsch.KnownHosts
*/
public void setKnownHosts(InputStream stream) throws JSchException{
if(known_hosts==null) known_hosts=new KnownHosts(this);
if(known_hosts instanceof KnownHosts){
synchronized(known_hosts){
((KnownHosts)known_hosts).setKnownHosts(stream);
}
}
}
/**
* Returns the current hostkey repository.
* By the default, this method will the instance of <code>KnownHosts</code>.
*
* @return current hostkey repository.
*
* @see com.jcraft.jsch.HostKeyRepository
* @see com.jcraft.jsch.KnownHosts
*/
public HostKeyRepository getHostKeyRepository(){
if(known_hosts==null) known_hosts=new KnownHosts(this);
return known_hosts;
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
*
* @param prvkey filename of the private key.
*
* @throws JSchException if <code>prvkey</code> is invalid.
*
* @see #addIdentity(String prvkey, String passphrase)
*/
public void addIdentity(String prvkey) throws JSchException{
addIdentity(prvkey, (byte[])null);
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
* Before registering it into identityRepository,
* it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param passphrase passphrase for <code>prvkey</code>.
*
* @throws JSchException if <code>passphrase</code> is not right.
*
* @see #addIdentity(String prvkey, byte[] passphrase)
*/
public void addIdentity(String prvkey, String passphrase) throws JSchException{
byte[] _passphrase=null;
if(passphrase!=null){
_passphrase=Util.str2byte(passphrase);
}
addIdentity(prvkey, _passphrase);
if(_passphrase!=null)
Util.bzero(_passphrase);
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
* Before registering it into identityRepository,
* it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param passphrase passphrase for <code>prvkey</code>.
*
* @throws JSchException if <code>passphrase</code> is not right.
*
* @see #addIdentity(String prvkey, String pubkey, byte[] passphrase)
*/
public void addIdentity(String prvkey, byte[] passphrase) throws JSchException{
Identity identity=IdentityFile.newInstance(prvkey, null, this);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
* Before registering it into identityRepository,
* it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param pubkey filename of the public key.
* @param passphrase passphrase for <code>prvkey</code>.
*
* @throws JSchException if <code>passphrase</code> is not right.
*/
public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException{
Identity identity=IdentityFile.newInstance(prvkey, pubkey, this);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
* Before registering it into identityRepository,
* it will be deciphered with <code>passphrase</code>.
*
* @param name name of the identity to be used to
retrieve it in the identityRepository.
* @param prvkey private key in byte array.
* @param pubkey public key in byte array.
* @param passphrase passphrase for <code>prvkey</code>.
*
*/
public void addIdentity(String name, byte[]prvkey, byte[]pubkey, byte[] passphrase) throws JSchException{
Identity identity=IdentityFile.newInstance(name, prvkey, pubkey, this);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in
* the public key authentication.
* Before registering it into identityRepository,
* it will be deciphered with <code>passphrase</code>.
*
* @param identity private key.
* @param passphrase passphrase for <code>identity</code>.
*
* @throws JSchException if <code>passphrase</code> is not right.
*/
public void addIdentity(Identity identity, byte[] passphrase) throws JSchException{
if(passphrase!=null){
try{
byte[] goo=new byte[passphrase.length];
System.arraycopy(passphrase, 0, goo, 0, passphrase.length);
passphrase=goo;
identity.setPassphrase(passphrase);
}
finally{
Util.bzero(passphrase);
}
}
if(identityRepository instanceof LocalIdentityRepository){
((LocalIdentityRepository)identityRepository).add(identity);
}
else if(identity instanceof IdentityFile && !identity.isEncrypted()) {
identityRepository.add(((IdentityFile)identity).getKeyPair().forSSHAgent());
}
else {
synchronized(this){
if(!(identityRepository instanceof IdentityRepository.Wrapper)){
setIdentityRepository(new IdentityRepository.Wrapper(identityRepository));
}
}
((IdentityRepository.Wrapper)identityRepository).add(identity);
}
}
/**
* @deprecated use #removeIdentity(Identity identity)
*/
public void removeIdentity(String name) throws JSchException{
Vector identities = identityRepository.getIdentities();
for(int i=0; i<identities.size(); i++){
Identity identity=(Identity)(identities.elementAt(i));
if(!identity.getName().equals(name))
continue;
if(identityRepository instanceof LocalIdentityRepository){
((LocalIdentityRepository)identityRepository).remove(identity);
}
else
identityRepository.remove(identity.getPublicKeyBlob());
}
}
/**
* Removes the identity from identityRepository.
*
* @param identity the indentity to be removed.
*
* @throws JSchException if <code>identity</code> is invalid.
*/
public void removeIdentity(Identity identity) throws JSchException{
identityRepository.remove(identity.getPublicKeyBlob());
}
/**
* Lists names of identities included in the identityRepository.
*
* @return names of identities
*
* @throws JSchException if identityReposory has problems.
*/
public Vector getIdentityNames() throws JSchException{
Vector foo=new Vector();
Vector identities = identityRepository.getIdentities();
for(int i=0; i<identities.size(); i++){
Identity identity=(Identity)(identities.elementAt(i));
foo.addElement(identity.getName());
}
return foo;
}
/**
* Removes all identities from identityRepository.
*
* @throws JSchException if identityReposory has problems.
*/
public void removeAllIdentity() throws JSchException{
identityRepository.removeAll();
}
/**
* Returns the config value for the specified key.
*
* @param key key for the configuration.
* @return config value
*/
public static String getConfig(String key){
synchronized(config){
return (String)(config.get(key));
}
}
/**
* Sets or Overrides the configuration.
*
* @param newconf configurations
*/
public static void setConfig(java.util.Hashtable newconf){
synchronized(config){
for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) {
String key=(String)(e.nextElement());
config.put(key, (String)(newconf.get(key)));
}
}
}
/**
* Sets or Overrides the configuration.
*
* @param key key for the configuration
* @param value value for the configuration
*/
public static void setConfig(String key, String value){
config.put(key, value);
}
/**
* Sets the logger
*
* @param logger logger
*
* @see com.jcraft.jsch.Logger
*/
public static void setLogger(Logger logger){
if(logger==null) logger=DEVNULL;
JSch.logger=logger;
}
static Logger getLogger(){
return logger;
}
}

View File

@ -0,0 +1,45 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class JSchAuthCancelException extends JSchException{
//private static final long serialVersionUID=3204965907117900987L;
String method;
JSchAuthCancelException () {
super();
}
JSchAuthCancelException (String s) {
super(s);
this.method=s;
}
public String getMethod(){
return method;
}
}

View File

@ -0,0 +1,48 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class JSchException extends Exception{
//private static final long serialVersionUID=-1319309923966731989L;
private Throwable cause=null;
public JSchException () {
super();
}
public JSchException (String s) {
super(s);
}
public JSchException (String s, Throwable e) {
super(s);
this.cause=e;
}
public Throwable getCause(){
return this.cause;
}
}

View File

@ -0,0 +1,45 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class JSchPartialAuthException extends JSchException{
//private static final long serialVersionUID=-378849862323360367L;
String methods;
public JSchPartialAuthException () {
super();
}
public JSchPartialAuthException (String s) {
super(s);
this.methods=s;
}
public String getMethods(){
return methods;
}
}

View File

@ -0,0 +1,183 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public abstract class KeyExchange{
static final int PROPOSAL_KEX_ALGS=0;
static final int PROPOSAL_SERVER_HOST_KEY_ALGS=1;
static final int PROPOSAL_ENC_ALGS_CTOS=2;
static final int PROPOSAL_ENC_ALGS_STOC=3;
static final int PROPOSAL_MAC_ALGS_CTOS=4;
static final int PROPOSAL_MAC_ALGS_STOC=5;
static final int PROPOSAL_COMP_ALGS_CTOS=6;
static final int PROPOSAL_COMP_ALGS_STOC=7;
static final int PROPOSAL_LANG_CTOS=8;
static final int PROPOSAL_LANG_STOC=9;
static final int PROPOSAL_MAX=10;
//static String kex_algs="diffie-hellman-group-exchange-sha1"+
// ",diffie-hellman-group1-sha1";
//static String kex="diffie-hellman-group-exchange-sha1";
static String kex="diffie-hellman-group1-sha1";
static String server_host_key="ssh-rsa,ssh-dss";
static String enc_c2s="blowfish-cbc";
static String enc_s2c="blowfish-cbc";
static String mac_c2s="hmac-md5"; // hmac-md5,hmac-sha1,hmac-ripemd160,
// hmac-sha1-96,hmac-md5-96
static String mac_s2c="hmac-md5";
//static String comp_c2s="none"; // zlib
//static String comp_s2c="none";
static String lang_c2s="";
static String lang_s2c="";
public static final int STATE_END=0;
protected Session session=null;
protected HASH sha=null;
protected byte[] K=null;
protected byte[] H=null;
protected byte[] K_S=null;
public abstract void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception;
public abstract boolean next(Buffer buf) throws Exception;
public abstract String getKeyType();
public abstract int getState();
/*
void dump(byte[] foo){
for(int i=0; i<foo.length; i++){
if((foo[i]&0xf0)==0)System.err.print("0");
System.err.print(Integer.toHexString(foo[i]&0xff));
if(i%16==15){System.err.println(""); continue;}
if(i%2==1)System.err.print(" ");
}
}
*/
protected static String[] guess(byte[]I_S, byte[]I_C){
String[] guess=new String[PROPOSAL_MAX];
Buffer sb=new Buffer(I_S); sb.setOffSet(17);
Buffer cb=new Buffer(I_C); cb.setOffSet(17);
if(JSch.getLogger().isEnabled(Logger.INFO)){
for(int i=0; i<PROPOSAL_MAX; i++){
JSch.getLogger().log(Logger.INFO,
"kex: server: "+Util.byte2str(sb.getString()));
}
for(int i=0; i<PROPOSAL_MAX; i++){
JSch.getLogger().log(Logger.INFO,
"kex: client: "+Util.byte2str(cb.getString()));
}
sb.setOffSet(17);
cb.setOffSet(17);
}
for(int i=0; i<PROPOSAL_MAX; i++){
byte[] sp=sb.getString(); // server proposal
byte[] cp=cb.getString(); // client proposal
int j=0;
int k=0;
loop:
while(j<cp.length){
while(j<cp.length && cp[j]!=',')j++;
if(k==j) return null;
String algorithm=Util.byte2str(cp, k, j-k);
int l=0;
int m=0;
while(l<sp.length){
while(l<sp.length && sp[l]!=',')l++;
if(m==l) return null;
if(algorithm.equals(Util.byte2str(sp, m, l-m))){
guess[i]=algorithm;
break loop;
}
l++;
m=l;
}
j++;
k=j;
}
if(j==0){
guess[i]="";
}
else if(guess[i]==null){
return null;
}
}
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"kex: server->client"+
" "+guess[PROPOSAL_ENC_ALGS_STOC]+
" "+guess[PROPOSAL_MAC_ALGS_STOC]+
" "+guess[PROPOSAL_COMP_ALGS_STOC]);
JSch.getLogger().log(Logger.INFO,
"kex: client->server"+
" "+guess[PROPOSAL_ENC_ALGS_CTOS]+
" "+guess[PROPOSAL_MAC_ALGS_CTOS]+
" "+guess[PROPOSAL_COMP_ALGS_CTOS]);
}
return guess;
}
public String getFingerPrint(){
HASH hash=null;
try{
Class c=Class.forName(session.getConfig("md5"));
hash=(HASH)(c.newInstance());
}
catch(Exception e){ System.err.println("getFingerPrint: "+e); }
return Util.getFingerPrint(hash, getHostKey());
}
byte[] getK(){ return K; }
byte[] getH(){ return H; }
HASH getHash(){ return sha; }
byte[] getHostKey(){ return K_S; }
/*
* It seems JCE included in Oracle's Java7u6(and later) has suddenly changed
* its behavior. The secrete generated by KeyAgreement#generateSecret()
* may start with 0, even if it is a positive value.
*/
protected byte[] normalize(byte[] secret) {
if(secret.length > 1 &&
secret[0] == 0 && (secret[1]&0x80) == 0) {
byte[] tmp=new byte[secret.length-1];
System.arraycopy(secret, 1, tmp, 0, tmp.length);
secret=tmp;
}
return secret;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,332 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class KeyPairDSA extends KeyPair{
private byte[] P_array;
private byte[] Q_array;
private byte[] G_array;
private byte[] pub_array;
private byte[] prv_array;
//private int key_size=0;
private int key_size=1024;
public KeyPairDSA(JSch jsch){
this(jsch, null, null, null, null, null);
}
public KeyPairDSA(JSch jsch,
byte[] P_array,
byte[] Q_array,
byte[] G_array,
byte[] pub_array,
byte[] prv_array){
super(jsch);
this.P_array = P_array;
this.Q_array = Q_array;
this.G_array = G_array;
this.pub_array = pub_array;
this.prv_array = prv_array;
if(P_array!=null)
key_size = (new java.math.BigInteger(P_array)).bitLength();
}
void generate(int key_size) throws JSchException{
this.key_size=key_size;
try{
Class c=Class.forName(jsch.getConfig("keypairgen.dsa"));
KeyPairGenDSA keypairgen=(KeyPairGenDSA)(c.newInstance());
keypairgen.init(key_size);
P_array=keypairgen.getP();
Q_array=keypairgen.getQ();
G_array=keypairgen.getG();
pub_array=keypairgen.getY();
prv_array=keypairgen.getX();
keypairgen=null;
}
catch(Exception e){
//System.err.println("KeyPairDSA: "+e);
if(e instanceof Throwable)
throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString());
}
}
private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----");
private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----");
byte[] getBegin(){ return begin; }
byte[] getEnd(){ return end; }
byte[] getPrivateKey(){
int content=
1+countLength(1) + 1 + // INTEGER
1+countLength(P_array.length) + P_array.length + // INTEGER P
1+countLength(Q_array.length) + Q_array.length + // INTEGER Q
1+countLength(G_array.length) + G_array.length + // INTEGER G
1+countLength(pub_array.length) + pub_array.length + // INTEGER pub
1+countLength(prv_array.length) + prv_array.length; // INTEGER prv
int total=
1+countLength(content)+content; // SEQUENCE
byte[] plain=new byte[total];
int index=0;
index=writeSEQUENCE(plain, index, content);
index=writeINTEGER(plain, index, new byte[1]); // 0
index=writeINTEGER(plain, index, P_array);
index=writeINTEGER(plain, index, Q_array);
index=writeINTEGER(plain, index, G_array);
index=writeINTEGER(plain, index, pub_array);
index=writeINTEGER(plain, index, prv_array);
return plain;
}
boolean parse(byte[] plain){
try{
if(vendor==VENDOR_FSECURE){
if(plain[0]!=0x30){ // FSecure
Buffer buf=new Buffer(plain);
buf.getInt();
P_array=buf.getMPIntBits();
G_array=buf.getMPIntBits();
Q_array=buf.getMPIntBits();
pub_array=buf.getMPIntBits();
prv_array=buf.getMPIntBits();
if(P_array!=null)
key_size = (new java.math.BigInteger(P_array)).bitLength();
return true;
}
return false;
}
else if(vendor==VENDOR_PUTTY){
Buffer buf=new Buffer(plain);
buf.skip(plain.length);
try {
byte[][] tmp = buf.getBytes(1, "");
prv_array = tmp[0];
}
catch(JSchException e){
return false;
}
return true;
}
int index=0;
int length=0;
if(plain[index]!=0x30)return false;
index++; // SEQUENCE
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
if(plain[index]!=0x02)return false;
index++; // INTEGER
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
P_array=new byte[length];
System.arraycopy(plain, index, P_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
Q_array=new byte[length];
System.arraycopy(plain, index, Q_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
G_array=new byte[length];
System.arraycopy(plain, index, G_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
pub_array=new byte[length];
System.arraycopy(plain, index, pub_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
prv_array=new byte[length];
System.arraycopy(plain, index, prv_array, 0, length);
index+=length;
if(P_array!=null)
key_size = (new java.math.BigInteger(P_array)).bitLength();
}
catch(Exception e){
//System.err.println(e);
//e.printStackTrace();
return false;
}
return true;
}
public byte[] getPublicKeyBlob(){
byte[] foo=super.getPublicKeyBlob();
if(foo!=null) return foo;
if(P_array==null) return null;
byte[][] tmp = new byte[5][];
tmp[0] = sshdss;
tmp[1] = P_array;
tmp[2] = Q_array;
tmp[3] = G_array;
tmp[4] = pub_array;
return Buffer.fromBytes(tmp).buffer;
}
private static final byte[] sshdss=Util.str2byte("ssh-dss");
byte[] getKeyTypeName(){return sshdss;}
public int getKeyType(){return DSA;}
public int getKeySize(){
return key_size;
}
public byte[] getSignature(byte[] data){
try{
Class c=Class.forName((String)jsch.getConfig("signature.dss"));
SignatureDSA dsa=(SignatureDSA)(c.newInstance());
dsa.init();
dsa.setPrvKey(prv_array, P_array, Q_array, G_array);
dsa.update(data);
byte[] sig = dsa.sign();
byte[][] tmp = new byte[2][];
tmp[0] = sshdss;
tmp[1] = sig;
return Buffer.fromBytes(tmp).buffer;
}
catch(Exception e){
//System.err.println("e "+e);
}
return null;
}
public Signature getVerifier(){
try{
Class c=Class.forName((String)jsch.getConfig("signature.dss"));
SignatureDSA dsa=(SignatureDSA)(c.newInstance());
dsa.init();
if(pub_array == null && P_array == null && getPublicKeyBlob()!=null){
Buffer buf = new Buffer(getPublicKeyBlob());
buf.getString();
P_array = buf.getString();
Q_array = buf.getString();
G_array = buf.getString();
pub_array = buf.getString();
}
dsa.setPubKey(pub_array, P_array, Q_array, G_array);
return dsa;
}
catch(Exception e){
//System.err.println("e "+e);
}
return null;
}
static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException {
byte[][] tmp = buf.getBytes(7, "invalid key format");
byte[] P_array = tmp[1];
byte[] Q_array = tmp[2];
byte[] G_array = tmp[3];
byte[] pub_array = tmp[4];
byte[] prv_array = tmp[5];
KeyPairDSA kpair = new KeyPairDSA(jsch,
P_array, Q_array, G_array,
pub_array, prv_array);
kpair.publicKeyComment = new String(tmp[6]);
kpair.vendor=VENDOR_OPENSSH;
return kpair;
}
public byte[] forSSHAgent() throws JSchException {
if(isEncrypted()){
throw new JSchException("key is encrypted.");
}
Buffer buf = new Buffer();
buf.putString(sshdss);
buf.putString(P_array);
buf.putString(Q_array);
buf.putString(G_array);
buf.putString(pub_array);
buf.putString(prv_array);
buf.putString(Util.str2byte(publicKeyComment));
byte[] result = new byte[buf.getLength()];
buf.getByte(result, 0, result.length);
return result;
}
public void dispose(){
super.dispose();
Util.bzero(prv_array);
}
}

View File

@ -0,0 +1,39 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface KeyPairGenDSA{
void init(int key_size) throws Exception;
byte[] getX();
byte[] getY();
byte[] getP();
byte[] getQ();
byte[] getG();
}

View File

@ -0,0 +1,43 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface KeyPairGenRSA{
void init(int key_size) throws Exception;
byte[] getD();
byte[] getE();
byte[] getN();
byte[] getC();
byte[] getEP();
byte[] getEQ();
byte[] getP();
byte[] getQ();
}

View File

@ -0,0 +1,418 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.math.BigInteger;
public class KeyPairRSA extends KeyPair{
private byte[] n_array; // modulus p multiply q
private byte[] pub_array; // e
private byte[] prv_array; // d e^-1 mod (p-1)(q-1)
private byte[] p_array; // prime p
private byte[] q_array; // prime q
private byte[] ep_array; // prime exponent p dmp1 == prv mod (p-1)
private byte[] eq_array; // prime exponent q dmq1 == prv mod (q-1)
private byte[] c_array; // coefficient iqmp == modinv(q, p) == q^-1 mod p
private int key_size=1024;
public KeyPairRSA(JSch jsch){
this(jsch, null, null, null);
}
public KeyPairRSA(JSch jsch,
byte[] n_array,
byte[] pub_array,
byte[] prv_array){
super(jsch);
this.n_array = n_array;
this.pub_array = pub_array;
this.prv_array = prv_array;
if(n_array!=null){
key_size = (new java.math.BigInteger(n_array)).bitLength();
}
}
void generate(int key_size) throws JSchException{
this.key_size=key_size;
try{
Class c=Class.forName(jsch.getConfig("keypairgen.rsa"));
KeyPairGenRSA keypairgen=(KeyPairGenRSA)(c.newInstance());
keypairgen.init(key_size);
pub_array=keypairgen.getE();
prv_array=keypairgen.getD();
n_array=keypairgen.getN();
p_array=keypairgen.getP();
q_array=keypairgen.getQ();
ep_array=keypairgen.getEP();
eq_array=keypairgen.getEQ();
c_array=keypairgen.getC();
keypairgen=null;
}
catch(Exception e){
//System.err.println("KeyPairRSA: "+e);
if(e instanceof Throwable)
throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString());
}
}
private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----");
private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----");
byte[] getBegin(){ return begin; }
byte[] getEnd(){ return end; }
byte[] getPrivateKey(){
int content=
1+countLength(1) + 1 + // INTEGER
1+countLength(n_array.length) + n_array.length + // INTEGER N
1+countLength(pub_array.length) + pub_array.length + // INTEGER pub
1+countLength(prv_array.length) + prv_array.length+ // INTEGER prv
1+countLength(p_array.length) + p_array.length+ // INTEGER p
1+countLength(q_array.length) + q_array.length+ // INTEGER q
1+countLength(ep_array.length) + ep_array.length+ // INTEGER ep
1+countLength(eq_array.length) + eq_array.length+ // INTEGER eq
1+countLength(c_array.length) + c_array.length; // INTEGER c
int total=
1+countLength(content)+content; // SEQUENCE
byte[] plain=new byte[total];
int index=0;
index=writeSEQUENCE(plain, index, content);
index=writeINTEGER(plain, index, new byte[1]); // 0
index=writeINTEGER(plain, index, n_array);
index=writeINTEGER(plain, index, pub_array);
index=writeINTEGER(plain, index, prv_array);
index=writeINTEGER(plain, index, p_array);
index=writeINTEGER(plain, index, q_array);
index=writeINTEGER(plain, index, ep_array);
index=writeINTEGER(plain, index, eq_array);
index=writeINTEGER(plain, index, c_array);
return plain;
}
boolean parse(byte [] plain){
try{
int index=0;
int length=0;
if(vendor==VENDOR_PUTTY){
Buffer buf = new Buffer(plain);
buf.skip(plain.length);
try {
byte[][] tmp = buf.getBytes(4, "");
prv_array = tmp[0];
p_array = tmp[1];
q_array = tmp[2];
c_array = tmp[3];
}
catch(JSchException e){
return false;
}
getEPArray();
getEQArray();
return true;
}
if(vendor==VENDOR_FSECURE){
if(plain[index]!=0x30){ // FSecure
Buffer buf=new Buffer(plain);
pub_array=buf.getMPIntBits();
prv_array=buf.getMPIntBits();
n_array=buf.getMPIntBits();
byte[] u_array=buf.getMPIntBits();
p_array=buf.getMPIntBits();
q_array=buf.getMPIntBits();
if(n_array!=null){
key_size = (new java.math.BigInteger(n_array)).bitLength();
}
getEPArray();
getEQArray();
getCArray();
return true;
}
return false;
}
/*
Key must be in the following ASN.1 DER encoding,
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
*/
index++; // SEQUENCE
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
if(plain[index]!=0x02)return false;
index++; // INTEGER
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
n_array=new byte[length];
System.arraycopy(plain, index, n_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
pub_array=new byte[length];
System.arraycopy(plain, index, pub_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
prv_array=new byte[length];
System.arraycopy(plain, index, prv_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
p_array=new byte[length];
System.arraycopy(plain, index, p_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
q_array=new byte[length];
System.arraycopy(plain, index, q_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
ep_array=new byte[length];
System.arraycopy(plain, index, ep_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
eq_array=new byte[length];
System.arraycopy(plain, index, eq_array, 0, length);
index+=length;
index++;
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
c_array=new byte[length];
System.arraycopy(plain, index, c_array, 0, length);
index+=length;
if(n_array!=null){
key_size = (new java.math.BigInteger(n_array)).bitLength();
}
}
catch(Exception e){
//System.err.println(e);
return false;
}
return true;
}
public byte[] getPublicKeyBlob(){
byte[] foo=super.getPublicKeyBlob();
if(foo!=null) return foo;
if(pub_array==null) return null;
byte[][] tmp = new byte[3][];
tmp[0] = sshrsa;
tmp[1] = pub_array;
tmp[2] = n_array;
return Buffer.fromBytes(tmp).buffer;
}
private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
byte[] getKeyTypeName(){return sshrsa;}
public int getKeyType(){return RSA;}
public int getKeySize(){
return key_size;
}
public byte[] getSignature(byte[] data){
try{
Class c=Class.forName((String)jsch.getConfig("signature.rsa"));
SignatureRSA rsa=(SignatureRSA)(c.newInstance());
rsa.init();
rsa.setPrvKey(prv_array, n_array);
rsa.update(data);
byte[] sig = rsa.sign();
byte[][] tmp = new byte[2][];
tmp[0] = sshrsa;
tmp[1] = sig;
return Buffer.fromBytes(tmp).buffer;
}
catch(Exception e){
}
return null;
}
public Signature getVerifier(){
try{
Class c=Class.forName((String)jsch.getConfig("signature.rsa"));
SignatureRSA rsa=(SignatureRSA)(c.newInstance());
rsa.init();
if(pub_array == null && n_array == null && getPublicKeyBlob()!=null){
Buffer buf = new Buffer(getPublicKeyBlob());
buf.getString();
pub_array = buf.getString();
n_array = buf.getString();
}
rsa.setPubKey(pub_array, n_array);
return rsa;
}
catch(Exception e){
}
return null;
}
static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException {
byte[][] tmp = buf.getBytes(8, "invalid key format");
byte[] n_array = tmp[1];
byte[] pub_array = tmp[2];
byte[] prv_array = tmp[3];
KeyPairRSA kpair = new KeyPairRSA(jsch, n_array, pub_array, prv_array);
kpair.c_array = tmp[4]; // iqmp
kpair.p_array = tmp[5];
kpair.q_array = tmp[6];
kpair.publicKeyComment = new String(tmp[7]);
kpair.vendor=VENDOR_OPENSSH;
return kpair;
}
public byte[] forSSHAgent() throws JSchException {
if(isEncrypted()){
throw new JSchException("key is encrypted.");
}
Buffer buf = new Buffer();
buf.putString(sshrsa);
buf.putString(n_array);
buf.putString(pub_array);
buf.putString(prv_array);
buf.putString(getCArray());
buf.putString(p_array);
buf.putString(q_array);
buf.putString(Util.str2byte(publicKeyComment));
byte[] result = new byte[buf.getLength()];
buf.getByte(result, 0, result.length);
return result;
}
private byte[] getEPArray(){
if(ep_array==null){
ep_array=(new BigInteger(prv_array)).mod(new BigInteger(p_array).subtract(BigInteger.ONE)).toByteArray();
}
return ep_array;
}
private byte[] getEQArray(){
if(eq_array==null){
eq_array=(new BigInteger(prv_array)).mod(new BigInteger(q_array).subtract(BigInteger.ONE)).toByteArray();
}
return eq_array;
}
private byte[] getCArray(){
if(c_array==null){
c_array=(new BigInteger(q_array)).modInverse(new BigInteger(p_array)).toByteArray();
}
return c_array;
}
public void dispose(){
super.dispose();
Util.bzero(prv_array);
}
}

View File

@ -0,0 +1,584 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
public
class KnownHosts implements HostKeyRepository{
private static final String _known_hosts="known_hosts";
/*
static final int SSHDSS=0;
static final int SSHRSA=1;
static final int UNKNOWN=2;
*/
private JSch jsch=null;
private String known_hosts=null;
private java.util.Vector pool=null;
private MAC hmacsha1=null;
KnownHosts(JSch jsch){
super();
this.jsch=jsch;
pool=new java.util.Vector();
}
void setKnownHosts(String foo) throws JSchException{
try{
known_hosts = foo;
FileInputStream fis=new FileInputStream(Util.checkTilde(foo));
setKnownHosts(fis);
}
catch(FileNotFoundException e){
}
}
void setKnownHosts(InputStream foo) throws JSchException{
pool.removeAllElements();
StringBuffer sb=new StringBuffer();
byte i;
int j;
boolean error=false;
try{
InputStream fis=foo;
String host;
String key=null;
int type;
byte[] buf=new byte[1024];
int bufl=0;
loop:
while(true){
bufl=0;
while(true){
j=fis.read();
if(j==-1){
if(bufl==0){ break loop; }
else{ break; }
}
if(j==0x0d){ continue; }
if(j==0x0a){ break; }
if(buf.length<=bufl){
if(bufl>1024*10) break; // too long...
byte[] newbuf=new byte[buf.length*2];
System.arraycopy(buf, 0, newbuf, 0, buf.length);
buf=newbuf;
}
buf[bufl++]=(byte)j;
}
j=0;
while(j<bufl){
i=buf[j];
if(i==' '||i=='\t'){ j++; continue; }
if(i=='#'){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
break;
}
if(j>=bufl){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
sb.setLength(0);
while(j<bufl){
i=buf[j++];
if(i==0x20 || i=='\t'){ break; }
sb.append((char)i);
}
host=sb.toString();
if(j>=bufl || host.length()==0){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
while(j<bufl){
i=buf[j];
if(i==' '||i=='\t'){ j++; continue; }
break;
}
String marker="";
if(host.charAt(0) == '@'){
marker = host;
sb.setLength(0);
while(j<bufl){
i=buf[j++];
if(i==0x20 || i=='\t'){ break; }
sb.append((char)i);
}
host=sb.toString();
if(j>=bufl || host.length()==0){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
while(j<bufl){
i=buf[j];
if(i==' '||i=='\t'){ j++; continue; }
break;
}
}
sb.setLength(0);
type=-1;
while(j<bufl){
i=buf[j++];
if(i==0x20 || i=='\t'){ break; }
sb.append((char)i);
}
if(sb.toString().equals("ssh-dss")){ type=HostKey.SSHDSS; }
else if(sb.toString().equals("ssh-rsa")){ type=HostKey.SSHRSA; }
else { j=bufl; }
if(j>=bufl){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
while(j<bufl){
i=buf[j];
if(i==' '||i=='\t'){ j++; continue; }
break;
}
sb.setLength(0);
while(j<bufl){
i=buf[j++];
if(i==0x0d){ continue; }
if(i==0x0a){ break; }
if(i==0x20 || i=='\t'){ break; }
sb.append((char)i);
}
key=sb.toString();
if(key.length()==0){
addInvalidLine(Util.byte2str(buf, 0, bufl));
continue loop;
}
while(j<bufl){
i=buf[j];
if(i==' '||i=='\t'){ j++; continue; }
break;
}
/**
"man sshd" has following descriptions,
Note that the lines in these files are typically hundreds
of characters long, and you definitely don't want to type
in the host keys by hand. Rather, generate them by a script,
ssh-keyscan(1) or by taking /usr/local/etc/ssh_host_key.pub and
adding the host names at the front.
This means that a comment is allowed to appear at the end of each
key entry.
*/
String comment=null;
if(j<bufl){
sb.setLength(0);
while(j<bufl){
i=buf[j++];
if(i==0x0d){ continue; }
if(i==0x0a){ break; }
sb.append((char)i);
}
comment=sb.toString();
}
//System.err.println(host);
//System.err.println("|"+key+"|");
HostKey hk = null;
hk = new HashedHostKey(marker, host, type,
Util.fromBase64(Util.str2byte(key), 0,
key.length()), comment);
pool.addElement(hk);
}
fis.close();
if(error){
throw new JSchException("KnownHosts: invalid format");
}
}
catch(Exception e){
if(e instanceof JSchException)
throw (JSchException)e;
if(e instanceof Throwable)
throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString());
}
}
private void addInvalidLine(String line) throws JSchException {
HostKey hk = new HostKey(line, HostKey.UNKNOWN, null);
pool.addElement(hk);
}
String getKnownHostsFile(){ return known_hosts; }
public String getKnownHostsRepositoryID(){ return known_hosts; }
public int check(String host, byte[] key){
int result=NOT_INCLUDED;
if(host==null){
return result;
}
int type=getType(key);
HostKey hk;
synchronized(pool){
for(int i=0; i<pool.size(); i++){
hk=(HostKey)(pool.elementAt(i));
if(hk.isMatched(host) && hk.type==type){
if(Util.array_equals(hk.key, key)){
return OK;
}
else{
result=CHANGED;
}
}
}
}
if(result==NOT_INCLUDED &&
host.startsWith("[") &&
host.indexOf("]:")>1
){
return check(host.substring(1, host.indexOf("]:")), key);
}
return result;
}
public void add(HostKey hostkey, UserInfo userinfo){
int type=hostkey.type;
String host=hostkey.getHost();
byte[] key=hostkey.key;
HostKey hk=null;
synchronized(pool){
for(int i=0; i<pool.size(); i++){
hk=(HostKey)(pool.elementAt(i));
if(hk.isMatched(host) && hk.type==type){
/*
if(Util.array_equals(hk.key, key)){ return; }
if(hk.host.equals(host)){
hk.key=key;
return;
}
else{
hk.host=deleteSubString(hk.host, host);
break;
}
*/
}
}
}
hk=hostkey;
pool.addElement(hk);
String bar=getKnownHostsRepositoryID();
if(bar!=null){
boolean foo=true;
File goo=new File(Util.checkTilde(bar));
if(!goo.exists()){
foo=false;
if(userinfo!=null){
foo=userinfo.promptYesNo(bar+" does not exist.\n"+
"Are you sure you want to create it?"
);
goo=goo.getParentFile();
if(foo && goo!=null && !goo.exists()){
foo=userinfo.promptYesNo("The parent directory "+goo+" does not exist.\n"+
"Are you sure you want to create it?"
);
if(foo){
if(!goo.mkdirs()){
userinfo.showMessage(goo+" has not been created.");
foo=false;
}
else{
userinfo.showMessage(goo+" has been succesfully created.\nPlease check its access permission.");
}
}
}
if(goo==null)foo=false;
}
}
if(foo){
try{
sync(bar);
}
catch(Exception e){ System.err.println("sync known_hosts: "+e); }
}
}
}
public HostKey[] getHostKey(){
return getHostKey(null, (String)null);
}
public HostKey[] getHostKey(String host, String type){
synchronized(pool){
int count=0;
for(int i=0; i<pool.size(); i++){
HostKey hk=(HostKey)pool.elementAt(i);
if(hk.type==HostKey.UNKNOWN) continue;
if(host==null ||
(hk.isMatched(host) &&
(type==null || hk.getType().equals(type)))){
count++;
}
}
if(count==0)return null;
HostKey[] foo=new HostKey[count];
int j=0;
for(int i=0; i<pool.size(); i++){
HostKey hk=(HostKey)pool.elementAt(i);
if(hk.type==HostKey.UNKNOWN) continue;
if(host==null ||
(hk.isMatched(host) &&
(type==null || hk.getType().equals(type)))){
foo[j++]=hk;
}
}
return foo;
}
}
public void remove(String host, String type){
remove(host, type, null);
}
public void remove(String host, String type, byte[] key){
boolean sync=false;
synchronized(pool){
for(int i=0; i<pool.size(); i++){
HostKey hk=(HostKey)(pool.elementAt(i));
if(host==null ||
(hk.isMatched(host) &&
(type==null || (hk.getType().equals(type) &&
(key==null || Util.array_equals(key, hk.key)))))){
String hosts=hk.getHost();
if(hosts.equals(host) ||
((hk instanceof HashedHostKey) &&
((HashedHostKey)hk).isHashed())){
pool.removeElement(hk);
}
else{
hk.host=deleteSubString(hosts, host);
}
sync=true;
}
}
}
if(sync){
try{sync();}catch(Exception e){};
}
}
protected void sync() throws IOException {
if(known_hosts!=null)
sync(known_hosts);
}
protected synchronized void sync(String foo) throws IOException {
if(foo==null) return;
FileOutputStream fos=new FileOutputStream(Util.checkTilde(foo));
dump(fos);
fos.close();
}
private static final byte[] space={(byte)0x20};
private static final byte[] cr=Util.str2byte("\n");
void dump(OutputStream out) throws IOException {
try{
HostKey hk;
synchronized(pool){
for(int i=0; i<pool.size(); i++){
hk=(HostKey)(pool.elementAt(i));
//hk.dump(out);
String marker=hk.getMarker();
String host=hk.getHost();
String type=hk.getType();
String comment = hk.getComment();
if(type.equals("UNKNOWN")){
out.write(Util.str2byte(host));
out.write(cr);
continue;
}
if(marker.length()!=0){
out.write(Util.str2byte(marker));
out.write(space);
}
out.write(Util.str2byte(host));
out.write(space);
out.write(Util.str2byte(type));
out.write(space);
out.write(Util.str2byte(hk.getKey()));
if(comment!=null){
out.write(space);
out.write(Util.str2byte(comment));
}
out.write(cr);
}
}
}
catch(Exception e){
System.err.println(e);
}
}
private int getType(byte[] key){
if(key[8]=='d') return HostKey.SSHDSS;
if(key[8]=='r') return HostKey.SSHRSA;
return HostKey.UNKNOWN;
}
private String deleteSubString(String hosts, String host){
int i=0;
int hostlen=host.length();
int hostslen=hosts.length();
int j;
while(i<hostslen){
j=hosts.indexOf(',', i);
if(j==-1) break;
if(!host.equals(hosts.substring(i, j))){
i=j+1;
continue;
}
return hosts.substring(0, i)+hosts.substring(j+1);
}
if(hosts.endsWith(host) && hostslen-i==hostlen){
return hosts.substring(0, (hostlen==hostslen) ? 0 :hostslen-hostlen-1);
}
return hosts;
}
private synchronized MAC getHMACSHA1(){
if(hmacsha1==null){
try{
Class c=Class.forName(jsch.getConfig("hmac-sha1"));
hmacsha1=(MAC)(c.newInstance());
}
catch(Exception e){
System.err.println("hmacsha1: "+e);
}
}
return hmacsha1;
}
HostKey createHashedHostKey(String host, byte[]key) throws JSchException {
HashedHostKey hhk=new HashedHostKey(host, key);
hhk.hash();
return hhk;
}
class HashedHostKey extends HostKey{
private static final String HASH_MAGIC="|1|";
private static final String HASH_DELIM="|";
private boolean hashed=false;
byte[] salt=null;
byte[] hash=null;
HashedHostKey(String host, byte[] key) throws JSchException {
this(host, GUESS, key);
}
HashedHostKey(String host, int type, byte[] key) throws JSchException {
this("", host, type, key, null);
}
HashedHostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException {
super(marker, host, type, key, comment);
if(this.host.startsWith(HASH_MAGIC) &&
this.host.substring(HASH_MAGIC.length()).indexOf(HASH_DELIM)>0){
String data=this.host.substring(HASH_MAGIC.length());
String _salt=data.substring(0, data.indexOf(HASH_DELIM));
String _hash=data.substring(data.indexOf(HASH_DELIM)+1);
salt=Util.fromBase64(Util.str2byte(_salt), 0, _salt.length());
hash=Util.fromBase64(Util.str2byte(_hash), 0, _hash.length());
if(salt.length!=20 || // block size of hmac-sha1
hash.length!=20){
salt=null;
hash=null;
return;
}
hashed=true;
}
}
boolean isMatched(String _host){
if(!hashed){
return super.isMatched(_host);
}
MAC macsha1=getHMACSHA1();
try{
synchronized(macsha1){
macsha1.init(salt);
byte[] foo=Util.str2byte(_host);
macsha1.update(foo, 0, foo.length);
byte[] bar=new byte[macsha1.getBlockSize()];
macsha1.doFinal(bar, 0);
return Util.array_equals(hash, bar);
}
}
catch(Exception e){
System.out.println(e);
}
return false;
}
boolean isHashed(){
return hashed;
}
void hash(){
if(hashed)
return;
MAC macsha1=getHMACSHA1();
if(salt==null){
Random random=Session.random;
synchronized(random){
salt=new byte[macsha1.getBlockSize()];
random.fill(salt, 0, salt.length);
}
}
try{
synchronized(macsha1){
macsha1.init(salt);
byte[] foo=Util.str2byte(host);
macsha1.update(foo, 0, foo.length);
hash=new byte[macsha1.getBlockSize()];
macsha1.doFinal(hash, 0);
}
}
catch(Exception e){
}
host=HASH_MAGIC+Util.byte2str(Util.toBase64(salt, 0, salt.length))+
HASH_DELIM+Util.byte2str(Util.toBase64(hash, 0, hash.length));
hashed=true;
}
}
}

View File

@ -0,0 +1,103 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
class LocalIdentityRepository implements IdentityRepository {
private static final String name = "Local Identity Repository";
private Vector identities = new Vector();
private JSch jsch;
LocalIdentityRepository(JSch jsch){
this.jsch = jsch;
}
public String getName(){
return name;
}
public int getStatus(){
return RUNNING;
}
public synchronized Vector getIdentities() {
Vector v = new Vector();
for(int i=0; i<identities.size(); i++){
v.addElement(identities.elementAt(i));
}
return v;
}
public synchronized void add(Identity identity) {
if(!identities.contains(identity)) {
identities.addElement(identity);
}
}
public synchronized boolean add(byte[] identity) {
try{
Identity _identity =
IdentityFile.newInstance("from remote:", identity, null, jsch);
identities.addElement(_identity);
return true;
}
catch(JSchException e){
return false;
}
}
synchronized void remove(Identity identity) {
identities.removeElement(identity);
}
public synchronized boolean remove(byte[] blob) {
if(blob == null) return false;
for(int i=0; i<identities.size(); i++) {
Identity _identity = (Identity)(identities.elementAt(i));
byte[] _blob = _identity.getPublicKeyBlob();
if(_blob == null || !Util.array_equals(blob, _blob))
continue;
identities.removeElement(_identity);
_identity.clear();
return true;
}
return false;
}
public synchronized void removeAll() {
for(int i=0; i<identities.size(); i++) {
Identity identity=(Identity)(identities.elementAt(i));
identity.clear();
}
identities.removeAllElements();
}
}

View File

@ -0,0 +1,54 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Logger{
public final int DEBUG=0;
public final int INFO=1;
public final int WARN=2;
public final int ERROR=3;
public final int FATAL=4;
public boolean isEnabled(int level);
public void log(int level, String message);
/*
public final Logger SIMPLE_LOGGER=new Logger(){
public boolean isEnabled(int level){return true;}
public void log(int level, String message){System.err.println(message);}
};
final Logger DEVNULL=new Logger(){
public boolean isEnabled(int level){return false;}
public void log(int level, String message){}
};
*/
}

View File

@ -0,0 +1,39 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface MAC{
String getName();
int getBlockSize();
void init(byte[] key) throws Exception;
void update(byte[] foo, int start, int len);
void update(int foo);
void doFinal(byte[] buf, int offset);
}

View File

@ -0,0 +1,264 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2013 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
/**
* This class implements ConfigRepository interface, and parses
* OpenSSH's configuration file. The following keywords will be recognized,
* <ul>
* <li>Host</li>
* <li>User</li>
* <li>Hostname</li>
* <li>Port</li>
* <li>PreferredAuthentications</li>
* <li>IdentityFile</li>
* <li>NumberOfPasswordPrompts</li>
* <li>ConnectTimeout</li>
* <li>HostKeyAlias</li>
* <li>UserKnownHostsFile</li>
* <li>KexAlgorithms</li>
* <li>HostKeyAlgorithms</li>
* <li>Ciphers</li>
* <li>Macs</li>
* <li>Compression</li>
* <li>CompressionLevel</li>
* <li>ForwardAgent</li>
* <li>RequestTTY</li>
* <li>ServerAliveInterval</li>
* <li>LocalForward</li>
* <li>RemoteForward</li>
* <li>ClearAllForwardings</li>
* </ul>
*
* @see ConfigRepository
*/
public class OpenSSHConfig implements ConfigRepository {
/**
* Parses the given string, and returns an instance of ConfigRepository.
*
* @param conf string, which includes OpenSSH's config
* @return an instanceof OpenSSHConfig
*/
public static OpenSSHConfig parse(String conf) throws IOException {
InputStream in = new ByteArrayInputStream(Util.str2byte(conf));
try {
return new OpenSSHConfig(in);
}
finally {
in.close();
}
}
/**
* Parses the given file, and returns an instance of ConfigRepository.
*
* @param file OpenSSH's config file
* @return an instanceof OpenSSHConfig
*/
public static OpenSSHConfig parseFile(String file) throws IOException {
byte[] conf = Util.fromFile(file);
InputStream in = new ByteArrayInputStream(conf);
try {
return new OpenSSHConfig(in);
}
finally {
in.close();
}
}
OpenSSHConfig(InputStream in) throws IOException {
_parse(in);
}
private final Hashtable config = new Hashtable();
private final Vector hosts = new Vector();
private void _parse(InputStream in) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String host = "";
Vector/*<String[]>*/ kv = new Vector();
String l = null;
while((l = br.readLine()) != null){
l = l.trim();
if(l.length() == 0 || l.startsWith("#"))
continue;
String[] key_value = l.split("[= \t]", 2);
for(int i = 0; i < key_value.length; i++)
key_value[i] = key_value[i].trim();
if(key_value.length <= 1)
continue;
if(key_value[0].equals("Host")){
config.put(host, kv);
hosts.addElement(host);
host = key_value[1];
kv = new Vector();
}
else {
kv.addElement(key_value);
}
}
config.put(host, kv);
hosts.addElement(host);
}
public Config getConfig(String host) {
return new MyConfig(host);
}
private static final Hashtable keymap = new Hashtable();
static {
keymap.put("kex", "KexAlgorithms");
keymap.put("server_host_key", "HostKeyAlgorithms");
keymap.put("cipher.c2s", "Ciphers");
keymap.put("cipher.s2c", "Ciphers");
keymap.put("mac.c2s", "Macs");
keymap.put("mac.s2c", "Macs");
keymap.put("compression.s2c", "Compression");
keymap.put("compression.c2s", "Compression");
keymap.put("compression_level", "CompressionLevel");
keymap.put("MaxAuthTries", "NumberOfPasswordPrompts");
}
class MyConfig implements Config {
private String host;
private Vector _configs = new Vector();
MyConfig(String host){
this.host = host;
_configs.addElement(config.get(""));
byte[] _host = Util.str2byte(host);
if(hosts.size() > 1){
for(int i = 1; i < hosts.size(); i++){
String patterns[] = ((String)hosts.elementAt(i)).split("[ \t]");
for(int j = 0; j < patterns.length; j++){
boolean negate = false;
String foo = patterns[j].trim();
if(foo.startsWith("!")){
negate = true;
foo = foo.substring(1).trim();
}
if(Util.glob(Util.str2byte(foo), _host)){
if(!negate){
_configs.addElement(config.get((String)hosts.elementAt(i)));
}
}
else if(negate){
_configs.addElement(config.get((String)hosts.elementAt(i)));
}
}
}
}
}
private String find(String key) {
if(keymap.get(key)!=null) {
key = (String)keymap.get(key);
}
String value = null;
for(int i = 0; i < _configs.size(); i++) {
Vector v = (Vector)_configs.elementAt(i);
for(int j = 0; j < v.size(); j++) {
String[] kv = (String[])v.elementAt(j);
if(kv[0].equals(key)) {
value = kv[1];
break;
}
}
if(value != null)
break;
}
return value;
}
private String[] multiFind(String key) {
Vector value = new Vector();
for(int i = 0; i < _configs.size(); i++) {
Vector v = (Vector)_configs.elementAt(i);
for(int j = 0; j < v.size(); j++) {
String[] kv = (String[])v.elementAt(j);
if(kv[0].equals(key)) {
String foo = kv[1];
if(foo != null) {
value.remove(foo);
value.addElement(foo);
}
}
}
}
String[] result = new String[value.size()];
value.toArray(result);
return result;
}
public String getHostname(){ return find("Hostname"); }
public String getUser(){ return find("User"); }
public int getPort(){
String foo = find("Port");
int port = -1;
try {
port = Integer.parseInt(foo);
}
catch(NumberFormatException e){
// wrong format
}
return port;
}
public String getValue(String key){
if(key.equals("compression.s2c") ||
key.equals("compression.c2s")) {
String foo = find(key);
if(foo == null || foo.equals("no"))
return "none,zlib@openssh.com,zlib";
return "zlib@openssh.com,zlib,none";
}
return find(key);
}
public String[] getValues(String key){ return multiFind(key); }
}
}

View File

@ -0,0 +1,115 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class Packet{
private static Random random=null;
static void setRandom(Random foo){ random=foo;}
Buffer buffer;
byte[] ba4=new byte[4];
public Packet(Buffer buffer){
this.buffer=buffer;
}
public void reset(){
buffer.index=5;
}
void padding(int bsize){
int len=buffer.index;
int pad=(-len)&(bsize-1);
if(pad<bsize){
pad+=bsize;
}
len=len+pad-4;
ba4[0]=(byte)(len>>>24);
ba4[1]=(byte)(len>>>16);
ba4[2]=(byte)(len>>>8);
ba4[3]=(byte)(len);
System.arraycopy(ba4, 0, buffer.buffer, 0, 4);
buffer.buffer[4]=(byte)pad;
synchronized(random){
random.fill(buffer.buffer, buffer.index, pad);
}
buffer.skip(pad);
//buffer.putPad(pad);
/*
for(int i=0; i<buffer.index; i++){
System.err.print(Integer.toHexString(buffer.buffer[i]&0xff)+":");
}
System.err.println("");
*/
}
int shift(int len, int bsize, int mac){
int s=len+5+9;
int pad=(-s)&(bsize-1);
if(pad<bsize)pad+=bsize;
s+=pad;
s+=mac;
s+=32; // margin for deflater; deflater may inflate data
/**/
if(buffer.buffer.length<s+buffer.index-5-9-len){
byte[] foo=new byte[s+buffer.index-5-9-len];
System.arraycopy(buffer.buffer, 0, foo, 0, buffer.buffer.length);
buffer.buffer=foo;
}
/**/
//if(buffer.buffer.length<len+5+9)
// System.err.println("buffer.buffer.length="+buffer.buffer.length+" len+5+9="+(len+5+9));
//if(buffer.buffer.length<s)
// System.err.println("buffer.buffer.length="+buffer.buffer.length+" s="+(s));
System.arraycopy(buffer.buffer,
len+5+9,
buffer.buffer, s, buffer.index-5-9-len);
buffer.index=10;
buffer.putInt(len);
buffer.index=len+5+9;
return s;
}
void unshift(byte command, int recipient, int s, int len){
System.arraycopy(buffer.buffer,
s,
buffer.buffer, 5+9, len);
buffer.buffer[5]=command;
buffer.index=6;
buffer.putInt(recipient);
buffer.putInt(len);
buffer.index=len+5+9;
}
Buffer getBuffer(){
return buffer;
}
}

View File

@ -0,0 +1,209 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
import java.io.*;
class PortWatcher implements Runnable{
private static java.util.Vector pool=new java.util.Vector();
private static InetAddress anyLocalAddress=null;
static{
// 0.0.0.0
/*
try{ anyLocalAddress=InetAddress.getByAddress(new byte[4]); }
catch(UnknownHostException e){
}
*/
try{ anyLocalAddress=InetAddress.getByName("0.0.0.0"); }
catch(UnknownHostException e){
}
}
Session session;
int lport;
int rport;
String host;
InetAddress boundaddress;
Runnable thread;
ServerSocket ss;
int connectTimeout=0;
static String[] getPortForwarding(Session session){
java.util.Vector foo=new java.util.Vector();
synchronized(pool){
for(int i=0; i<pool.size(); i++){
PortWatcher p=(PortWatcher)(pool.elementAt(i));
if(p.session==session){
foo.addElement(p.lport+":"+p.host+":"+p.rport);
}
}
}
String[] bar=new String[foo.size()];
for(int i=0; i<foo.size(); i++){
bar[i]=(String)(foo.elementAt(i));
}
return bar;
}
static PortWatcher getPort(Session session, String address, int lport) throws JSchException{
InetAddress addr;
try{
addr=InetAddress.getByName(address);
}
catch(UnknownHostException uhe){
throw new JSchException("PortForwardingL: invalid address "+address+" specified.", uhe);
}
synchronized(pool){
for(int i=0; i<pool.size(); i++){
PortWatcher p=(PortWatcher)(pool.elementAt(i));
if(p.session==session && p.lport==lport){
if(/*p.boundaddress.isAnyLocalAddress() ||*/
(anyLocalAddress!=null && p.boundaddress.equals(anyLocalAddress)) ||
p.boundaddress.equals(addr))
return p;
}
}
return null;
}
}
private static String normalize(String address){
if(address!=null){
if(address.length()==0 || address.equals("*"))
address="0.0.0.0";
else if(address.equals("localhost"))
address="127.0.0.1";
}
return address;
}
static PortWatcher addPort(Session session, String address, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException{
address = normalize(address);
if(getPort(session, address, lport)!=null){
throw new JSchException("PortForwardingL: local port "+ address+":"+lport+" is already registered.");
}
PortWatcher pw=new PortWatcher(session, address, lport, host, rport, ssf);
pool.addElement(pw);
return pw;
}
static void delPort(Session session, String address, int lport) throws JSchException{
address = normalize(address);
PortWatcher pw=getPort(session, address, lport);
if(pw==null){
throw new JSchException("PortForwardingL: local port "+address+":"+lport+" is not registered.");
}
pw.delete();
pool.removeElement(pw);
}
static void delPort(Session session){
synchronized(pool){
PortWatcher[] foo=new PortWatcher[pool.size()];
int count=0;
for(int i=0; i<pool.size(); i++){
PortWatcher p=(PortWatcher)(pool.elementAt(i));
if(p.session==session) {
p.delete();
foo[count++]=p;
}
}
for(int i=0; i<count; i++){
PortWatcher p=foo[i];
pool.removeElement(p);
}
}
}
PortWatcher(Session session,
String address, int lport,
String host, int rport,
ServerSocketFactory factory) throws JSchException{
this.session=session;
this.lport=lport;
this.host=host;
this.rport=rport;
try{
boundaddress=InetAddress.getByName(address);
ss=(factory==null) ?
new ServerSocket(lport, 0, boundaddress) :
factory.createServerSocket(lport, 0, boundaddress);
}
catch(Exception e){
//System.err.println(e);
String message="PortForwardingL: local port "+address+":"+lport+" cannot be bound.";
if(e instanceof Throwable)
throw new JSchException(message, (Throwable)e);
throw new JSchException(message);
}
if(lport==0){
int assigned=ss.getLocalPort();
if(assigned!=-1)
this.lport=assigned;
}
}
public void run(){
thread=this;
try{
while(thread!=null){
Socket socket=ss.accept();
socket.setTcpNoDelay(true);
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
ChannelDirectTCPIP channel=new ChannelDirectTCPIP();
channel.init();
channel.setInputStream(in);
channel.setOutputStream(out);
session.addChannel(channel);
((ChannelDirectTCPIP)channel).setHost(host);
((ChannelDirectTCPIP)channel).setPort(rport);
((ChannelDirectTCPIP)channel).setOrgIPAddress(socket.getInetAddress().getHostAddress());
((ChannelDirectTCPIP)channel).setOrgPort(socket.getPort());
channel.connect(connectTimeout);
if(channel.exitstatus!=-1){
}
}
}
catch(Exception e){
//System.err.println("! "+e);
}
delete();
}
void delete(){
thread=null;
try{
if(ss!=null)ss.close();
ss=null;
}
catch(Exception e){
}
}
void setConnectTimeout(int connectTimeout){
this.connectTimeout=connectTimeout;
}
}

View File

@ -0,0 +1,40 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
import java.net.Socket;
public interface Proxy{
void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception;
InputStream getInputStream();
OutputStream getOutputStream();
Socket getSocket();
void close();
}

View File

@ -0,0 +1,180 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.*;
import java.net.*;
public class ProxyHTTP implements Proxy{
private static int DEFAULTPORT=80;
private String proxy_host;
private int proxy_port;
private InputStream in;
private OutputStream out;
private Socket socket;
private String user;
private String passwd;
public ProxyHTTP(String proxy_host){
int port=DEFAULTPORT;
String host=proxy_host;
if(proxy_host.indexOf(':')!=-1){
try{
host=proxy_host.substring(0, proxy_host.indexOf(':'));
port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
}
catch(Exception e){
}
}
this.proxy_host=host;
this.proxy_port=port;
}
public ProxyHTTP(String proxy_host, int proxy_port){
this.proxy_host=proxy_host;
this.proxy_port=proxy_port;
}
public void setUserPasswd(String user, String passwd){
this.user=user;
this.passwd=passwd;
}
public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
try{
if(socket_factory==null){
socket=Util.createSocket(proxy_host, proxy_port, timeout);
in=socket.getInputStream();
out=socket.getOutputStream();
}
else{
socket=socket_factory.createSocket(proxy_host, proxy_port);
in=socket_factory.getInputStream(socket);
out=socket_factory.getOutputStream(socket);
}
if(timeout>0){
socket.setSoTimeout(timeout);
}
socket.setTcpNoDelay(true);
out.write(Util.str2byte("CONNECT "+host+":"+port+" HTTP/1.0\r\n"));
if(user!=null && passwd!=null){
byte[] code=Util.str2byte(user+":"+passwd);
code=Util.toBase64(code, 0, code.length);
out.write(Util.str2byte("Proxy-Authorization: Basic "));
out.write(code);
out.write(Util.str2byte("\r\n"));
}
out.write(Util.str2byte("\r\n"));
out.flush();
int foo=0;
StringBuffer sb=new StringBuffer();
while(foo>=0){
foo=in.read(); if(foo!=13){sb.append((char)foo); continue;}
foo=in.read(); if(foo!=10){continue;}
break;
}
if(foo<0){
throw new IOException();
}
String response=sb.toString();
String reason="Unknow reason";
int code=-1;
try{
foo=response.indexOf(' ');
int bar=response.indexOf(' ', foo+1);
code=Integer.parseInt(response.substring(foo+1, bar));
reason=response.substring(bar+1);
}
catch(Exception e){
}
if(code!=200){
throw new IOException("proxy error: "+reason);
}
/*
while(foo>=0){
foo=in.read(); if(foo!=13) continue;
foo=in.read(); if(foo!=10) continue;
foo=in.read(); if(foo!=13) continue;
foo=in.read(); if(foo!=10) continue;
break;
}
*/
int count=0;
while(true){
count=0;
while(foo>=0){
foo=in.read(); if(foo!=13){count++; continue;}
foo=in.read(); if(foo!=10){continue;}
break;
}
if(foo<0){
throw new IOException();
}
if(count==0)break;
}
}
catch(RuntimeException e){
throw e;
}
catch(Exception e){
try{ if(socket!=null)socket.close(); }
catch(Exception eee){
}
String message="ProxyHTTP: "+e.toString();
if(e instanceof Throwable)
throw new JSchException(message, (Throwable)e);
throw new JSchException(message);
}
}
public InputStream getInputStream(){ return in; }
public OutputStream getOutputStream(){ return out; }
public Socket getSocket(){ return socket; }
public void close(){
try{
if(in!=null)in.close();
if(out!=null)out.close();
if(socket!=null)socket.close();
}
catch(Exception e){
}
in=null;
out=null;
socket=null;
}
public static int getDefaultPort(){
return DEFAULTPORT;
}
}

View File

@ -0,0 +1,212 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This file depends on following documents,
- SOCKS: A protocol for TCP proxy across firewalls, Ying-Da Lee
http://www.socks.nec.com/protocol/socks4.protocol
*/
package com.jcraft.jsch;
import java.io.*;
import java.net.*;
public class ProxySOCKS4 implements Proxy{
private static int DEFAULTPORT=1080;
private String proxy_host;
private int proxy_port;
private InputStream in;
private OutputStream out;
private Socket socket;
private String user;
private String passwd;
public ProxySOCKS4(String proxy_host){
int port=DEFAULTPORT;
String host=proxy_host;
if(proxy_host.indexOf(':')!=-1){
try{
host=proxy_host.substring(0, proxy_host.indexOf(':'));
port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
}
catch(Exception e){
}
}
this.proxy_host=host;
this.proxy_port=port;
}
public ProxySOCKS4(String proxy_host, int proxy_port){
this.proxy_host=proxy_host;
this.proxy_port=proxy_port;
}
public void setUserPasswd(String user, String passwd){
this.user=user;
this.passwd=passwd;
}
public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
try{
if(socket_factory==null){
socket=Util.createSocket(proxy_host, proxy_port, timeout);
//socket=new Socket(proxy_host, proxy_port);
in=socket.getInputStream();
out=socket.getOutputStream();
}
else{
socket=socket_factory.createSocket(proxy_host, proxy_port);
in=socket_factory.getInputStream(socket);
out=socket_factory.getOutputStream(socket);
}
if(timeout>0){
socket.setSoTimeout(timeout);
}
socket.setTcpNoDelay(true);
byte[] buf=new byte[1024];
int index=0;
/*
1) CONNECT
The client connects to the SOCKS server and sends a CONNECT request when
it wants to establish a connection to an application server. The client
includes in the request packet the IP address and the port number of the
destination host, and userid, in the following format.
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1
VN is the SOCKS protocol version number and should be 4. CD is the
SOCKS command code and should be 1 for CONNECT request. NULL is a byte
of all zero bits.
*/
index=0;
buf[index++]=4;
buf[index++]=1;
buf[index++]=(byte)(port>>>8);
buf[index++]=(byte)(port&0xff);
try{
InetAddress addr=InetAddress.getByName(host);
byte[] byteAddress = addr.getAddress();
for (int i = 0; i < byteAddress.length; i++) {
buf[index++]=byteAddress[i];
}
}
catch(UnknownHostException uhe){
throw new JSchException("ProxySOCKS4: "+uhe.toString(), uhe);
}
if(user!=null){
System.arraycopy(Util.str2byte(user), 0, buf, index, user.length());
index+=user.length();
}
buf[index++]=0;
out.write(buf, 0, index);
/*
The SOCKS server checks to see whether such a request should be granted
based on any combination of source IP address, destination IP address,
destination port number, the userid, and information it may obtain by
consulting IDENT, cf. RFC 1413. If the request is granted, the SOCKS
server makes a connection to the specified port of the destination host.
A reply packet is sent to the client when this connection is established,
or when the request is rejected or the operation fails.
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
# of bytes: 1 1 2 4
VN is the version of the reply code and should be 0. CD is the result
code with one of the following values:
90: request granted
91: request rejected or failed
92: request rejected becasue SOCKS server cannot connect to
identd on the client
93: request rejected because the client program and identd
report different user-ids
The remaining fields are ignored.
*/
int len=8;
int s=0;
while(s<len){
int i=in.read(buf, s, len-s);
if(i<=0){
throw new JSchException("ProxySOCKS4: stream is closed");
}
s+=i;
}
if(buf[0]!=0){
throw new JSchException("ProxySOCKS4: server returns VN "+buf[0]);
}
if(buf[1]!=90){
try{ socket.close(); }
catch(Exception eee){
}
String message="ProxySOCKS4: server returns CD "+buf[1];
throw new JSchException(message);
}
}
catch(RuntimeException e){
throw e;
}
catch(Exception e){
try{ if(socket!=null)socket.close(); }
catch(Exception eee){
}
throw new JSchException("ProxySOCKS4: "+e.toString());
}
}
public InputStream getInputStream(){ return in; }
public OutputStream getOutputStream(){ return out; }
public Socket getSocket(){ return socket; }
public void close(){
try{
if(in!=null)in.close();
if(out!=null)out.close();
if(socket!=null)socket.close();
}
catch(Exception e){
}
in=null;
out=null;
socket=null;
}
public static int getDefaultPort(){
return DEFAULTPORT;
}
}

View File

@ -0,0 +1,349 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This file depends on following documents,
- RFC 1928 SOCKS Protocol Verseion 5
- RFC 1929 Username/Password Authentication for SOCKS V5.
*/
package com.jcraft.jsch;
import java.io.*;
import java.net.*;
public class ProxySOCKS5 implements Proxy{
private static int DEFAULTPORT=1080;
private String proxy_host;
private int proxy_port;
private InputStream in;
private OutputStream out;
private Socket socket;
private String user;
private String passwd;
public ProxySOCKS5(String proxy_host){
int port=DEFAULTPORT;
String host=proxy_host;
if(proxy_host.indexOf(':')!=-1){
try{
host=proxy_host.substring(0, proxy_host.indexOf(':'));
port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
}
catch(Exception e){
}
}
this.proxy_host=host;
this.proxy_port=port;
}
public ProxySOCKS5(String proxy_host, int proxy_port){
this.proxy_host=proxy_host;
this.proxy_port=proxy_port;
}
public void setUserPasswd(String user, String passwd){
this.user=user;
this.passwd=passwd;
}
public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
try{
if(socket_factory==null){
socket=Util.createSocket(proxy_host, proxy_port, timeout);
//socket=new Socket(proxy_host, proxy_port);
in=socket.getInputStream();
out=socket.getOutputStream();
}
else{
socket=socket_factory.createSocket(proxy_host, proxy_port);
in=socket_factory.getInputStream(socket);
out=socket_factory.getOutputStream(socket);
}
if(timeout>0){
socket.setSoTimeout(timeout);
}
socket.setTcpNoDelay(true);
byte[] buf=new byte[1024];
int index=0;
/*
+----+----------+----------+
|VER | NMETHODS | METHODS |
+----+----------+----------+
| 1 | 1 | 1 to 255 |
+----+----------+----------+
The VER field is set to X'05' for this version of the protocol. The
NMETHODS field contains the number of method identifier octets that
appear in the METHODS field.
The values currently defined for METHOD are:
o X'00' NO AUTHENTICATION REQUIRED
o X'01' GSSAPI
o X'02' USERNAME/PASSWORD
o X'03' to X'7F' IANA ASSIGNED
o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
o X'FF' NO ACCEPTABLE METHODS
*/
buf[index++]=5;
buf[index++]=2;
buf[index++]=0; // NO AUTHENTICATION REQUIRED
buf[index++]=2; // USERNAME/PASSWORD
out.write(buf, 0, index);
/*
The server selects from one of the methods given in METHODS, and
sends a METHOD selection message:
+----+--------+
|VER | METHOD |
+----+--------+
| 1 | 1 |
+----+--------+
*/
//in.read(buf, 0, 2);
fill(in, buf, 2);
boolean check=false;
switch((buf[1])&0xff){
case 0: // NO AUTHENTICATION REQUIRED
check=true;
break;
case 2: // USERNAME/PASSWORD
if(user==null || passwd==null)break;
/*
Once the SOCKS V5 server has started, and the client has selected the
Username/Password Authentication protocol, the Username/Password
subnegotiation begins. This begins with the client producing a
Username/Password request:
+----+------+----------+------+----------+
|VER | ULEN | UNAME | PLEN | PASSWD |
+----+------+----------+------+----------+
| 1 | 1 | 1 to 255 | 1 | 1 to 255 |
+----+------+----------+------+----------+
The VER field contains the current version of the subnegotiation,
which is X'01'. The ULEN field contains the length of the UNAME field
that follows. The UNAME field contains the username as known to the
source operating system. The PLEN field contains the length of the
PASSWD field that follows. The PASSWD field contains the password
association with the given UNAME.
*/
index=0;
buf[index++]=1;
buf[index++]=(byte)(user.length());
System.arraycopy(Util.str2byte(user), 0, buf, index, user.length());
index+=user.length();
buf[index++]=(byte)(passwd.length());
System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length());
index+=passwd.length();
out.write(buf, 0, index);
/*
The server verifies the supplied UNAME and PASSWD, and sends the
following response:
+----+--------+
|VER | STATUS |
+----+--------+
| 1 | 1 |
+----+--------+
A STATUS field of X'00' indicates success. If the server returns a
`failure' (STATUS value other than X'00') status, it MUST close the
connection.
*/
//in.read(buf, 0, 2);
fill(in, buf, 2);
if(buf[1]==0)
check=true;
break;
default:
}
if(!check){
try{ socket.close(); }
catch(Exception eee){
}
throw new JSchException("fail in SOCKS5 proxy");
}
/*
The SOCKS request is formed as follows:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
Where:
o VER protocol version: X'05'
o CMD
o CONNECT X'01'
o BIND X'02'
o UDP ASSOCIATE X'03'
o RSV RESERVED
o ATYP address type of following address
o IP V4 address: X'01'
o DOMAINNAME: X'03'
o IP V6 address: X'04'
o DST.ADDR desired destination address
o DST.PORT desired destination port in network octet
order
*/
index=0;
buf[index++]=5;
buf[index++]=1; // CONNECT
buf[index++]=0;
byte[] hostb=Util.str2byte(host);
int len=hostb.length;
buf[index++]=3; // DOMAINNAME
buf[index++]=(byte)(len);
System.arraycopy(hostb, 0, buf, index, len);
index+=len;
buf[index++]=(byte)(port>>>8);
buf[index++]=(byte)(port&0xff);
out.write(buf, 0, index);
/*
The SOCKS request information is sent by the client as soon as it has
established a connection to the SOCKS server, and completed the
authentication negotiations. The server evaluates the request, and
returns a reply formed as follows:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
Where:
o VER protocol version: X'05'
o REP Reply field:
o X'00' succeeded
o X'01' general SOCKS server failure
o X'02' connection not allowed by ruleset
o X'03' Network unreachable
o X'04' Host unreachable
o X'05' Connection refused
o X'06' TTL expired
o X'07' Command not supported
o X'08' Address type not supported
o X'09' to X'FF' unassigned
o RSV RESERVED
o ATYP address type of following address
o IP V4 address: X'01'
o DOMAINNAME: X'03'
o IP V6 address: X'04'
o BND.ADDR server bound address
o BND.PORT server bound port in network octet order
*/
//in.read(buf, 0, 4);
fill(in, buf, 4);
if(buf[1]!=0){
try{ socket.close(); }
catch(Exception eee){
}
throw new JSchException("ProxySOCKS5: server returns "+buf[1]);
}
switch(buf[3]&0xff){
case 1:
//in.read(buf, 0, 6);
fill(in, buf, 6);
break;
case 3:
//in.read(buf, 0, 1);
fill(in, buf, 1);
//in.read(buf, 0, buf[0]+2);
fill(in, buf, (buf[0]&0xff)+2);
break;
case 4:
//in.read(buf, 0, 18);
fill(in, buf, 18);
break;
default:
}
}
catch(RuntimeException e){
throw e;
}
catch(Exception e){
try{ if(socket!=null)socket.close(); }
catch(Exception eee){
}
String message="ProxySOCKS5: "+e.toString();
if(e instanceof Throwable)
throw new JSchException(message, (Throwable)e);
throw new JSchException(message);
}
}
public InputStream getInputStream(){ return in; }
public OutputStream getOutputStream(){ return out; }
public Socket getSocket(){ return socket; }
public void close(){
try{
if(in!=null)in.close();
if(out!=null)out.close();
if(socket!=null)socket.close();
}
catch(Exception e){
}
in=null;
out=null;
socket=null;
}
public static int getDefaultPort(){
return DEFAULTPORT;
}
private void fill(InputStream in, byte[] buf, int len) throws JSchException, IOException{
int s=0;
while(s<len){
int i=in.read(buf, s, len-s);
if(i<=0){
throw new JSchException("ProxySOCKS5: stream is closed");
}
s+=i;
}
}
}

View File

@ -0,0 +1,34 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Random{
void fill(byte[] foo, int start, int len);
}

View File

@ -0,0 +1,69 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class Request{
private boolean reply=false;
private Session session=null;
private Channel channel=null;
void request(Session session, Channel channel) throws Exception{
this.session=session;
this.channel=channel;
if(channel.connectTimeout>0){
setReply(true);
}
}
boolean waitForReply(){ return reply; }
void setReply(boolean reply){ this.reply=reply; }
void write(Packet packet) throws Exception{
if(reply){
channel.reply=-1;
}
session.write(packet);
if(reply){
long start=System.currentTimeMillis();
long timeout=channel.connectTimeout;
while(channel.isConnected() && channel.reply==-1){
try{Thread.sleep(10);}
catch(Exception ee){
}
if(timeout>0L &&
(System.currentTimeMillis()-start)>timeout){
channel.reply=0;
throw new JSchException("channel request: timeout");
}
}
if(channel.reply==0){
throw new JSchException("failed to send channel request");
}
}
}
}

View File

@ -0,0 +1,53 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestAgentForwarding extends Request{
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
setReply(false);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
// byte SSH_MSG_CHANNEL_REQUEST(98)
// uint32 recipient channel
// string request type // "auth-agent-req@openssh.com"
// boolean want reply // 0
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("auth-agent-req@openssh.com"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
write(packet);
session.agent_forwarding=true;
}
}

View File

@ -0,0 +1,54 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestEnv extends Request{
byte[] name=new byte[0];
byte[] value=new byte[0];
void setEnv(byte[] name, byte[] value){
this.name=name;
this.value=value;
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("env"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putString(name);
buf.putString(value);
write(packet);
}
}

View File

@ -0,0 +1,58 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestExec extends Request{
private byte[] command=new byte[0];
RequestExec(byte[] command){
this.command=command;
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
// send
// byte SSH_MSG_CHANNEL_REQUEST(98)
// uint32 recipient channel
// string request type // "exec"
// boolean want reply // 0
// string command
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("exec"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.checkFreeSize(4+command.length);
buf.putString(command);
write(packet);
}
}

View File

@ -0,0 +1,78 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestPtyReq extends Request{
private String ttype="vt100";
private int tcol=80;
private int trow=24;
private int twp=640;
private int thp=480;
private byte[] terminal_mode=Util.empty;
void setCode(String cookie){
}
void setTType(String ttype){
this.ttype=ttype;
}
void setTerminalMode(byte[] terminal_mode){
this.terminal_mode=terminal_mode;
}
void setTSize(int tcol, int trow, int twp, int thp){
this.tcol=tcol;
this.trow=trow;
this.twp=twp;
this.thp=thp;
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("pty-req"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putString(Util.str2byte(ttype));
buf.putInt(tcol);
buf.putInt(trow);
buf.putInt(twp);
buf.putInt(thp);
buf.putString(terminal_mode);
write(packet);
}
}

View File

@ -0,0 +1,49 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class RequestSftp extends Request{
RequestSftp(){
setReply(true);
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("subsystem"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putString(Util.str2byte("sftp"));
write(packet);
}
}

View File

@ -0,0 +1,51 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestShell extends Request{
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
// send
// byte SSH_MSG_CHANNEL_REQUEST(98)
// uint32 recipient channel
// string request type // "shell"
// boolean want reply // 0
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("shell"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
write(packet);
}
}

View File

@ -0,0 +1,49 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestSignal extends Request{
private String signal="KILL";
public void setSignal(String foo){ signal=foo; }
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("signal"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putString(Util.str2byte(signal));
write(packet);
}
}

View File

@ -0,0 +1,53 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class RequestSubsystem extends Request{
private String subsystem=null;
public void request(Session session, Channel channel, String subsystem, boolean want_reply) throws Exception{
setReply(want_reply);
this.subsystem=subsystem;
this.request(session, channel);
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("subsystem"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putString(Util.str2byte(subsystem));
write(packet);
}
}

View File

@ -0,0 +1,68 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestWindowChange extends Request{
int width_columns=80;
int height_rows=24;
int width_pixels=640;
int height_pixels=480;
void setSize(int col, int row, int wp, int hp){
this.width_columns=col;
this.height_rows=row;
this.width_pixels=wp;
this.height_pixels=hp;
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
//byte SSH_MSG_CHANNEL_REQUEST
//uint32 recipient_channel
//string "window-change"
//boolean FALSE
//uint32 terminal width, columns
//uint32 terminal height, rows
//uint32 terminal width, pixels
//uint32 terminal height, pixels
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("window-change"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putInt(width_columns);
buf.putInt(height_rows);
buf.putInt(width_pixels);
buf.putInt(height_pixels);
write(packet);
}
}

View File

@ -0,0 +1,63 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class RequestX11 extends Request{
public void setCookie(String cookie){
ChannelX11.cookie=Util.str2byte(cookie);
}
public void request(Session session, Channel channel) throws Exception{
super.request(session, channel);
Buffer buf=new Buffer();
Packet packet=new Packet(buf);
// byte SSH_MSG_CHANNEL_REQUEST(98)
// uint32 recipient channel
// string request type // "x11-req"
// boolean want reply // 0
// boolean single connection
// string x11 authentication protocol // "MIT-MAGIC-COOKIE-1".
// string x11 authentication cookie
// uint32 x11 screen number
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
buf.putInt(channel.getRecipient());
buf.putString(Util.str2byte("x11-req"));
buf.putByte((byte)(waitForReply() ? 1 : 0));
buf.putByte((byte)0);
buf.putString(Util.str2byte("MIT-MAGIC-COOKIE-1"));
buf.putString(ChannelX11.getFakedCookie(session));
buf.putInt(0);
write(packet);
session.x11_forwarding=true;
}
}

View File

@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
import java.io.*;
public interface ServerSocketFactory{
public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
uint32 flags
uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID
uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID
uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
uint32 atime present only if flag SSH_FILEXFER_ACMODTIME
uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME
uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
string extended_type
string extended_data
... more extended data (extended_type - extended_data pairs),
so that number of pairs equals extended_count
*/
public class SftpATTRS {
static final int S_ISUID = 04000; // set user ID on execution
static final int S_ISGID = 02000; // set group ID on execution
static final int S_ISVTX = 01000; // sticky bit ****** NOT DOCUMENTED *****
static final int S_IRUSR = 00400; // read by owner
static final int S_IWUSR = 00200; // write by owner
static final int S_IXUSR = 00100; // execute/search by owner
static final int S_IREAD = 00400; // read by owner
static final int S_IWRITE= 00200; // write by owner
static final int S_IEXEC = 00100; // execute/search by owner
static final int S_IRGRP = 00040; // read by group
static final int S_IWGRP = 00020; // write by group
static final int S_IXGRP = 00010; // execute/search by group
static final int S_IROTH = 00004; // read by others
static final int S_IWOTH = 00002; // write by others
static final int S_IXOTH = 00001; // execute/search by others
private static final int pmask = 0xFFF;
public String getPermissionsString() {
StringBuffer buf = new StringBuffer(10);
if(isDir()) buf.append('d');
else if(isLink()) buf.append('l');
else buf.append('-');
if((permissions & S_IRUSR)!=0) buf.append('r');
else buf.append('-');
if((permissions & S_IWUSR)!=0) buf.append('w');
else buf.append('-');
if((permissions & S_ISUID)!=0) buf.append('s');
else if ((permissions & S_IXUSR)!=0) buf.append('x');
else buf.append('-');
if((permissions & S_IRGRP)!=0) buf.append('r');
else buf.append('-');
if((permissions & S_IWGRP)!=0) buf.append('w');
else buf.append('-');
if((permissions & S_ISGID)!=0) buf.append('s');
else if((permissions & S_IXGRP)!=0) buf.append('x');
else buf.append('-');
if((permissions & S_IROTH) != 0) buf.append('r');
else buf.append('-');
if((permissions & S_IWOTH) != 0) buf.append('w');
else buf.append('-');
if((permissions & S_IXOTH) != 0) buf.append('x');
else buf.append('-');
return (buf.toString());
}
public String getAtimeString(){
SimpleDateFormat locale=new SimpleDateFormat();
return (locale.format(new Date(atime)));
}
public String getMtimeString(){
Date date= new Date(((long)mtime)*1000);
return (date.toString());
}
public static final int SSH_FILEXFER_ATTR_SIZE= 0x00000001;
public static final int SSH_FILEXFER_ATTR_UIDGID= 0x00000002;
public static final int SSH_FILEXFER_ATTR_PERMISSIONS= 0x00000004;
public static final int SSH_FILEXFER_ATTR_ACMODTIME= 0x00000008;
public static final int SSH_FILEXFER_ATTR_EXTENDED= 0x80000000;
static final int S_IFMT=0xf000;
static final int S_IFIFO=0x1000;
static final int S_IFCHR=0x2000;
static final int S_IFDIR=0x4000;
static final int S_IFBLK=0x6000;
static final int S_IFREG=0x8000;
static final int S_IFLNK=0xa000;
static final int S_IFSOCK=0xc000;
int flags=0;
long size;
int uid;
int gid;
int permissions;
int atime;
int mtime;
String[] extended=null;
private SftpATTRS(){
}
static SftpATTRS getATTR(Buffer buf){
SftpATTRS attr=new SftpATTRS();
attr.flags=buf.getInt();
if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); }
if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
attr.uid=buf.getInt(); attr.gid=buf.getInt();
}
if((attr.flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){
attr.permissions=buf.getInt();
}
if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){
attr.atime=buf.getInt();
}
if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){
attr.mtime=buf.getInt();
}
if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
int count=buf.getInt();
if(count>0){
attr.extended=new String[count*2];
for(int i=0; i<count; i++){
attr.extended[i*2]=Util.byte2str(buf.getString());
attr.extended[i*2+1]=Util.byte2str(buf.getString());
}
}
}
return attr;
}
int length(){
int len=4;
if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ len+=8; }
if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){ len+=8; }
if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ len+=4; }
if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ len+=8; }
if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
len+=4;
int count=extended.length/2;
if(count>0){
for(int i=0; i<count; i++){
len+=4; len+=extended[i*2].length();
len+=4; len+=extended[i*2+1].length();
}
}
}
return len;
}
void dump(Buffer buf){
buf.putInt(flags);
if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ buf.putLong(size); }
if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
buf.putInt(uid); buf.putInt(gid);
}
if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){
buf.putInt(permissions);
}
if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(atime); }
if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(mtime); }
if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
int count=extended.length/2;
if(count>0){
for(int i=0; i<count; i++){
buf.putString(Util.str2byte(extended[i*2]));
buf.putString(Util.str2byte(extended[i*2+1]));
}
}
}
}
void setFLAGS(int flags){
this.flags=flags;
}
public void setSIZE(long size){
flags|=SSH_FILEXFER_ATTR_SIZE;
this.size=size;
}
public void setUIDGID(int uid, int gid){
flags|=SSH_FILEXFER_ATTR_UIDGID;
this.uid=uid;
this.gid=gid;
}
public void setACMODTIME(int atime, int mtime){
flags|=SSH_FILEXFER_ATTR_ACMODTIME;
this.atime=atime;
this.mtime=mtime;
}
public void setPERMISSIONS(int permissions){
flags|=SSH_FILEXFER_ATTR_PERMISSIONS;
permissions=(this.permissions&~pmask)|(permissions&pmask);
this.permissions=permissions;
}
private boolean isType(int mask) {
return (flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0 &&
(permissions&S_IFMT)==mask;
}
public boolean isReg(){
return isType(S_IFREG);
}
public boolean isDir(){
return isType(S_IFDIR);
}
public boolean isChr(){
return isType(S_IFCHR);
}
public boolean isBlk(){
return isType(S_IFBLK);
}
public boolean isFifo(){
return isType(S_IFIFO);
}
public boolean isLink(){
return isType(S_IFLNK);
}
public boolean isSock(){
return isType(S_IFSOCK);
}
public int getFlags() { return flags; }
public long getSize() { return size; }
public int getUId() { return uid; }
public int getGId() { return gid; }
public int getPermissions() { return permissions; }
public int getATime() { return atime; }
public int getMTime() { return mtime; }
public String[] getExtended() { return extended; }
public String toString() {
return (getPermissionsString()+" "+getUId()+" "+getGId()+" "+getSize()+" "+getMtimeString());
}
/*
public String toString(){
return (((flags&SSH_FILEXFER_ATTR_SIZE)!=0) ? ("size:"+size+" ") : "")+
(((flags&SSH_FILEXFER_ATTR_UIDGID)!=0) ? ("uid:"+uid+",gid:"+gid+" ") : "")+
(((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0) ? ("permissions:0x"+Integer.toHexString(permissions)+" ") : "")+
(((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) ? ("atime:"+atime+",mtime:"+mtime+" ") : "")+
(((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0) ? ("extended:?"+" ") : "");
}
*/
}

View File

@ -0,0 +1,51 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class SftpException extends Exception{
//private static final long serialVersionUID=-5616888495583253811L;
public int id;
private Throwable cause=null;
public SftpException (int id, String message) {
super(message);
this.id=id;
}
public SftpException (int id, String message, Throwable e) {
super(message);
this.id=id;
this.cause=e;
}
public String toString(){
return id+": "+getMessage();
}
public Throwable getCause(){
return this.cause;
}
}

View File

@ -0,0 +1,39 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface SftpProgressMonitor{
public static final int PUT=0;
public static final int GET=1;
public static final long UNKNOWN_SIZE = -1L;
void init(int op, String src, String dest, long max);
boolean count(long count);
void end();
}

View File

@ -0,0 +1,134 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SftpStatVFS {
/*
from "man statvfs"
struct statvfs {
unsigned long f_bsize; // file system block size
unsigned long f_frsize; // fragment size
fsblkcnt_t f_blocks; // size of fs in f_frsize units
fsblkcnt_t f_bfree; // # free blocks
fsblkcnt_t f_bavail; // # free blocks for non-root
fsfilcnt_t f_files; // # inodes
fsfilcnt_t f_ffree; // # free inodes
fsfilcnt_t f_favail; // # free inodes for non-root
unsigned long f_fsid; // file system ID
unsigned long f_flag; // mount flags
unsigned long f_namemax; // maximum filename length
};
*/
private long bsize;
private long frsize;
private long blocks;
private long bfree;
private long bavail;
private long files;
private long ffree;
private long favail;
private long fsid;
private long flag;
private long namemax;
int flags=0;
long size;
int uid;
int gid;
int permissions;
int atime;
int mtime;
String[] extended=null;
private SftpStatVFS(){
}
static SftpStatVFS getStatVFS(Buffer buf){
SftpStatVFS statvfs=new SftpStatVFS();
statvfs.bsize = buf.getLong();
statvfs.frsize = buf.getLong();
statvfs.blocks = buf.getLong();
statvfs.bfree = buf.getLong();
statvfs.bavail = buf.getLong();
statvfs.files = buf.getLong();
statvfs.ffree = buf.getLong();
statvfs.favail = buf.getLong();
statvfs.fsid = buf.getLong();
int flag = (int)buf.getLong();
statvfs.namemax = buf.getLong();
statvfs.flag =
(flag & 1/*SSH2_FXE_STATVFS_ST_RDONLY*/) != 0 ? 1/*ST_RDONLY*/ : 0;
statvfs.flag |=
(flag & 2/*SSH2_FXE_STATVFS_ST_NOSUID*/) != 0 ? 2/*ST_NOSUID*/ : 0;
return statvfs;
}
public long getBlockSize() { return bsize; }
public long getFragmentSize() { return frsize; }
public long getBlocks() { return blocks; }
public long getFreeBlocks() { return bfree; }
public long getAvailBlocks() { return bavail; }
public long getINodes() { return files; }
public long getFreeINodes() { return ffree; }
public long getAvailINodes() { return favail; }
public long getFileSystemID() { return fsid; }
public long getMountFlag() { return flag; }
public long getMaximumFilenameLength() { return namemax; }
public long getSize(){
return getFragmentSize()*getBlocks()/1024;
}
public long getUsed(){
return getFragmentSize()*(getBlocks()-getFreeBlocks())/1024;
}
public long getAvailForNonRoot(){
return getFragmentSize()*getAvailBlocks()/1024;
}
public long getAvail(){
return getFragmentSize()*getFreeBlocks()/1024;
}
public int getCapacity(){
return (int)(100*(getBlocks()-getFreeBlocks())/getBlocks());
}
// public String toString() { return ""; }
}

View File

@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2012-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Signature{
void init() throws Exception;
void update(byte[] H) throws Exception;
boolean verify(byte[] sig) throws Exception;
byte[] sign() throws Exception;
}

View File

@ -0,0 +1,35 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface SignatureDSA extends Signature {
void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception;
void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception;
}

View File

@ -0,0 +1,35 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface SignatureRSA extends Signature {
void setPubKey(byte[] e, byte[] n) throws Exception;
void setPrvKey(byte[] d, byte[] n) throws Exception;
}

View File

@ -0,0 +1,40 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.*;
import java.io.*;
public interface SocketFactory{
public Socket createSocket(String host, int port)throws IOException,
UnknownHostException;
public InputStream getInputStream(Socket socket)throws IOException;
public OutputStream getOutputStream(Socket socket)throws IOException;
}

View File

@ -0,0 +1,38 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface UIKeyboardInteractive{
String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo);
}

View File

@ -0,0 +1,53 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public abstract class UserAuth{
protected static final int SSH_MSG_USERAUTH_REQUEST= 50;
protected static final int SSH_MSG_USERAUTH_FAILURE= 51;
protected static final int SSH_MSG_USERAUTH_SUCCESS= 52;
protected static final int SSH_MSG_USERAUTH_BANNER= 53;
protected static final int SSH_MSG_USERAUTH_INFO_REQUEST= 60;
protected static final int SSH_MSG_USERAUTH_INFO_RESPONSE= 61;
protected static final int SSH_MSG_USERAUTH_PK_OK= 60;
protected UserInfo userinfo;
protected Packet packet;
protected Buffer buf;
protected String username;
public boolean start(Session session) throws Exception{
this.userinfo=session.getUserInfo();
this.packet=session.packet;
this.buf=packet.getBuffer();
this.username=session.getUserName();
return true;
}
}

View File

@ -0,0 +1,227 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class UserAuthGSSAPIWithMIC extends UserAuth {
private static final int SSH_MSG_USERAUTH_GSSAPI_RESPONSE= 60;
private static final int SSH_MSG_USERAUTH_GSSAPI_TOKEN= 61;
private static final int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE=63;
private static final int SSH_MSG_USERAUTH_GSSAPI_ERROR= 64;
private static final int SSH_MSG_USERAUTH_GSSAPI_ERRTOK= 65;
private static final int SSH_MSG_USERAUTH_GSSAPI_MIC= 66;
private static final byte[][] supported_oid={
// OID 1.2.840.113554.1.2.2 in DER
{(byte)0x6,(byte)0x9,(byte)0x2a,(byte)0x86,(byte)0x48,
(byte)0x86,(byte)0xf7,(byte)0x12,(byte)0x1,(byte)0x2,
(byte)0x2}
};
private static final String[] supported_method={
"gssapi-with-mic.krb5"
};
public boolean start(Session session)throws Exception{
super.start(session);
byte[] _username=Util.str2byte(username);
packet.reset();
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name(in ISO-10646 UTF-8 encoding)
// string service name(in US-ASCII)
// string "gssapi"(US-ASCII)
// uint32 n, the number of OIDs client supports
// string[n] mechanism OIDS
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("gssapi-with-mic"));
buf.putInt(supported_oid.length);
for(int i=0; i<supported_oid.length; i++){
buf.putString(supported_oid[i]);
}
session.write(packet);
String method=null;
int command;
while(true){
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_FAILURE){
return false;
}
if(command==SSH_MSG_USERAUTH_GSSAPI_RESPONSE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] message=buf.getString();
for(int i=0; i<supported_oid.length; i++){
if(Util.array_equals(message, supported_oid[i])){
method=supported_method[i];
break;
}
}
if(method==null){
return false;
}
break; // success
}
if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
userinfo.showMessage(message);
}
continue;
}
return false;
}
GSSContext context=null;
try{
Class c=Class.forName(session.getConfig(method));
context=(GSSContext)(c.newInstance());
}
catch(Exception e){
return false;
}
try{
context.create(username, session.host);
}
catch(JSchException e){
return false;
}
byte[] token=new byte[0];
while(!context.isEstablished()){
try{
token=context.init(token, 0, token.length);
}
catch(JSchException e){
// TODO
// ERRTOK should be sent?
// byte SSH_MSG_USERAUTH_GSSAPI_ERRTOK
// string error token
return false;
}
if(token!=null){
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN);
buf.putString(token);
session.write(packet);
}
if(!context.isEstablished()){
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_GSSAPI_ERROR){
// uint32 major_status
// uint32 minor_status
// string message
// string language tag
buf=session.read(buf);
command=buf.getCommand()&0xff;
//return false;
}
else if(command==SSH_MSG_USERAUTH_GSSAPI_ERRTOK){
// string error token
buf=session.read(buf);
command=buf.getCommand()&0xff;
//return false;
}
if(command==SSH_MSG_USERAUTH_FAILURE){
return false;
}
buf.getInt(); buf.getByte(); buf.getByte();
token=buf.getString();
}
}
Buffer mbuf=new Buffer();
// string session identifier
// byte SSH_MSG_USERAUTH_REQUEST
// string user name
// string service
// string "gssapi-with-mic"
mbuf.putString(session.getSessionId());
mbuf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
mbuf.putString(_username);
mbuf.putString(Util.str2byte("ssh-connection"));
mbuf.putString(Util.str2byte("gssapi-with-mic"));
byte[] mic=context.getMIC(mbuf.buffer, 0, mbuf.getLength());
if(mic==null){
return false;
}
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_MIC);
buf.putString(mic);
session.write(packet);
context.dispose();
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_SUCCESS){
return true;
}
else if(command==SSH_MSG_USERAUTH_FAILURE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] foo=buf.getString();
int partial_success=buf.getByte();
//System.err.println(new String(foo)+
// " partial_success:"+(partial_success!=0));
if(partial_success!=0){
throw new JSchPartialAuthException(Util.byte2str(foo));
}
}
return false;
}
}

View File

@ -0,0 +1,203 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class UserAuthKeyboardInteractive extends UserAuth{
public boolean start(Session session) throws Exception{
super.start(session);
if(userinfo!=null && !(userinfo instanceof UIKeyboardInteractive)){
return false;
}
String dest=username+"@"+session.host;
if(session.port!=22){
dest+=(":"+session.port);
}
byte[] password=session.password;
boolean cancel=false;
byte[] _username=null;
_username=Util.str2byte(username);
while(true){
if(session.auth_failures >= session.max_auth_tries){
return false;
}
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name (ISO-10646 UTF-8, as defined in [RFC-2279])
// string service name (US-ASCII) "ssh-userauth" ? "ssh-connection"
// string "keyboard-interactive" (US-ASCII)
// string language tag (as defined in [RFC-3066])
// string submethods (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
//buf.putString("ssh-userauth".getBytes());
buf.putString(Util.str2byte("keyboard-interactive"));
buf.putString(Util.empty);
buf.putString(Util.empty);
session.write(packet);
boolean firsttime=true;
loop:
while(true){
buf=session.read(buf);
int command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_SUCCESS){
return true;
}
if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
userinfo.showMessage(message);
}
continue loop;
}
if(command==SSH_MSG_USERAUTH_FAILURE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] foo=buf.getString();
int partial_success=buf.getByte();
// System.err.println(new String(foo)+
// " partial_success:"+(partial_success!=0));
if(partial_success!=0){
throw new JSchPartialAuthException(Util.byte2str(foo));
}
if(firsttime){
return false;
//throw new JSchException("USERAUTH KI is not supported");
//cancel=true; // ??
}
session.auth_failures++;
break;
}
if(command==SSH_MSG_USERAUTH_INFO_REQUEST){
firsttime=false;
buf.getInt(); buf.getByte(); buf.getByte();
String name=Util.byte2str(buf.getString());
String instruction=Util.byte2str(buf.getString());
String languate_tag=Util.byte2str(buf.getString());
int num=buf.getInt();
String[] prompt=new String[num];
boolean[] echo=new boolean[num];
for(int i=0; i<num; i++){
prompt[i]=Util.byte2str(buf.getString());
echo[i]=(buf.getByte()!=0);
}
byte[][] response=null;
if(password!=null &&
prompt.length==1 &&
!echo[0] &&
prompt[0].toLowerCase().indexOf("password:") >= 0){
response=new byte[1][];
response[0]=password;
password=null;
}
else if(num>0
||(name.length()>0 || instruction.length()>0)
){
if(userinfo!=null){
UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo;
String[] _response=kbi.promptKeyboardInteractive(dest,
name,
instruction,
prompt,
echo);
if(_response!=null){
response=new byte[_response.length][];
for(int i=0; i<_response.length; i++){
response[i]=Util.str2byte(_response[i]);
}
}
}
}
// byte SSH_MSG_USERAUTH_INFO_RESPONSE(61)
// int num-responses
// string response[1] (ISO-10646 UTF-8)
// ...
// string response[num-responses] (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE);
if(num>0 &&
(response==null || // cancel
num!=response.length)){
if(response==null){
// working around the bug in OpenSSH ;-<
buf.putInt(num);
for(int i=0; i<num; i++){
buf.putString(Util.empty);
}
}
else{
buf.putInt(0);
}
if(response==null)
cancel=true;
}
else{
buf.putInt(num);
for(int i=0; i<num; i++){
buf.putString(response[i]);
}
}
session.write(packet);
/*
if(cancel)
break;
*/
continue loop;
}
//throw new JSchException("USERAUTH fail ("+command+")");
return false;
}
if(cancel){
throw new JSchAuthCancelException("keyboard-interactive");
//break;
}
}
//return false;
}
}

View File

@ -0,0 +1,129 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class UserAuthNone extends UserAuth{
private static final int SSH_MSG_SERVICE_ACCEPT= 6;
private String methods=null;
public boolean start(Session session) throws Exception{
super.start(session);
// send
// byte SSH_MSG_SERVICE_REQUEST(5)
// string service name "ssh-userauth"
packet.reset();
buf.putByte((byte)Session.SSH_MSG_SERVICE_REQUEST);
buf.putString(Util.str2byte("ssh-userauth"));
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_SERVICE_REQUEST sent");
}
// receive
// byte SSH_MSG_SERVICE_ACCEPT(6)
// string service name
buf=session.read(buf);
int command=buf.getCommand();
boolean result=(command==SSH_MSG_SERVICE_ACCEPT);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_SERVICE_ACCEPT received");
}
if(!result)
return false;
byte[] _username=null;
_username=Util.str2byte(username);
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name
// string service name ("ssh-connection")
// string "none"
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("none"));
session.write(packet);
loop:
while(true){
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_SUCCESS){
return true;
}
if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
try{
userinfo.showMessage(message);
}
catch(RuntimeException ee){
}
}
continue loop;
}
if(command==SSH_MSG_USERAUTH_FAILURE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] foo=buf.getString();
int partial_success=buf.getByte();
methods=Util.byte2str(foo);
//System.err.println("UserAuthNONE: "+methods+
// " partial_success:"+(partial_success!=0));
// if(partial_success!=0){
// throw new JSchPartialAuthException(new String(foo));
// }
break;
}
else{
// System.err.println("USERAUTH fail ("+command+")");
throw new JSchException("USERAUTH fail ("+command+")");
}
}
//throw new JSchException("USERAUTH fail");
return false;
}
String getMethods(){
return methods;
}
}

View File

@ -0,0 +1,193 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class UserAuthPassword extends UserAuth{
private final int SSH_MSG_USERAUTH_PASSWD_CHANGEREQ=60;
public boolean start(Session session) throws Exception{
super.start(session);
byte[] password=session.password;
String dest=username+"@"+session.host;
if(session.port!=22){
dest+=(":"+session.port);
}
try{
while(true){
if(session.auth_failures >= session.max_auth_tries){
return false;
}
if(password==null){
if(userinfo==null){
//throw new JSchException("USERAUTH fail");
return false;
}
if(!userinfo.promptPassword("Password for "+dest)){
throw new JSchAuthCancelException("password");
//break;
}
String _password=userinfo.getPassword();
if(_password==null){
throw new JSchAuthCancelException("password");
//break;
}
password=Util.str2byte(_password);
}
byte[] _username=null;
_username=Util.str2byte(username);
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name
// string service name ("ssh-connection")
// string "password"
// boolen FALSE
// string plaintext password (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("password"));
buf.putByte((byte)0);
buf.putString(password);
session.write(packet);
loop:
while(true){
buf=session.read(buf);
int command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_SUCCESS){
return true;
}
if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
userinfo.showMessage(message);
}
continue loop;
}
if(command==SSH_MSG_USERAUTH_PASSWD_CHANGEREQ){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] instruction=buf.getString();
byte[] tag=buf.getString();
if(userinfo==null ||
!(userinfo instanceof UIKeyboardInteractive)){
if(userinfo!=null){
userinfo.showMessage("Password must be changed.");
}
return false;
}
UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo;
String[] response;
String name="Password Change Required";
String[] prompt={"New Password: "};
boolean[] echo={false};
response=kbi.promptKeyboardInteractive(dest,
name,
Util.byte2str(instruction),
prompt,
echo);
if(response==null){
throw new JSchAuthCancelException("password");
}
byte[] newpassword=Util.str2byte(response[0]);
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name
// string service name ("ssh-connection")
// string "password"
// boolen TRUE
// string plaintext old password (ISO-10646 UTF-8)
// string plaintext new password (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("password"));
buf.putByte((byte)1);
buf.putString(password);
buf.putString(newpassword);
Util.bzero(newpassword);
response=null;
session.write(packet);
continue loop;
}
if(command==SSH_MSG_USERAUTH_FAILURE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] foo=buf.getString();
int partial_success=buf.getByte();
//System.err.println(new String(foo)+
// " partial_success:"+(partial_success!=0));
if(partial_success!=0){
throw new JSchPartialAuthException(Util.byte2str(foo));
}
session.auth_failures++;
break;
}
else{
//System.err.println("USERAUTH fail ("+buf.getCommand()+")");
// throw new JSchException("USERAUTH fail ("+buf.getCommand()+")");
return false;
}
}
if(password!=null){
Util.bzero(password);
password=null;
}
}
}
finally{
if(password!=null){
Util.bzero(password);
password=null;
}
}
//throw new JSchException("USERAUTH fail");
//return false;
}
}

View File

@ -0,0 +1,231 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
class UserAuthPublicKey extends UserAuth{
public boolean start(Session session) throws Exception{
super.start(session);
Vector identities=session.getIdentityRepository().getIdentities();
byte[] passphrase=null;
byte[] _username=null;
int command;
synchronized(identities){
if(identities.size()<=0){
return false;
}
_username=Util.str2byte(username);
for(int i=0; i<identities.size(); i++){
if(session.auth_failures >= session.max_auth_tries){
return false;
}
Identity identity=(Identity)(identities.elementAt(i));
byte[] pubkeyblob=identity.getPublicKeyBlob();
if(pubkeyblob!=null){
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name
// string service name ("ssh-connection")
// string "publickey"
// boolen FALSE
// string plaintext password (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("publickey"));
buf.putByte((byte)0);
buf.putString(Util.str2byte(identity.getAlgName()));
buf.putString(pubkeyblob);
session.write(packet);
loop1:
while(true){
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_PK_OK){
break;
}
else if(command==SSH_MSG_USERAUTH_FAILURE){
break;
}
else if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
userinfo.showMessage(message);
}
continue loop1;
}
else{
//System.err.println("USERAUTH fail ("+command+")");
//throw new JSchException("USERAUTH fail ("+command+")");
break;
}
}
if(command!=SSH_MSG_USERAUTH_PK_OK){
continue;
}
}
//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
int count=5;
while(true){
if((identity.isEncrypted() && passphrase==null)){
if(userinfo==null) throw new JSchException("USERAUTH fail");
if(identity.isEncrypted() &&
!userinfo.promptPassphrase("Passphrase for "+identity.getName())){
throw new JSchAuthCancelException("publickey");
//throw new JSchException("USERAUTH cancel");
//break;
}
String _passphrase=userinfo.getPassphrase();
if(_passphrase!=null){
passphrase=Util.str2byte(_passphrase);
}
}
if(!identity.isEncrypted() || passphrase!=null){
if(identity.setPassphrase(passphrase)){
if(passphrase!=null &&
(session.getIdentityRepository() instanceof IdentityRepository.Wrapper)){
((IdentityRepository.Wrapper)session.getIdentityRepository()).check();
}
break;
}
}
Util.bzero(passphrase);
passphrase=null;
count--;
if(count==0)break;
}
Util.bzero(passphrase);
passphrase=null;
//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
if(identity.isEncrypted()) continue;
if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob();
//System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob);
if(pubkeyblob==null) continue;
// send
// byte SSH_MSG_USERAUTH_REQUEST(50)
// string user name
// string service name ("ssh-connection")
// string "publickey"
// boolen TRUE
// string plaintext password (ISO-10646 UTF-8)
packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username);
buf.putString(Util.str2byte("ssh-connection"));
buf.putString(Util.str2byte("publickey"));
buf.putByte((byte)1);
buf.putString(Util.str2byte(identity.getAlgName()));
buf.putString(pubkeyblob);
// byte[] tmp=new byte[buf.index-5];
// System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length);
// buf.putString(signature);
byte[] sid=session.getSessionId();
int sidlen=sid.length;
byte[] tmp=new byte[4+sidlen+buf.index-5];
tmp[0]=(byte)(sidlen>>>24);
tmp[1]=(byte)(sidlen>>>16);
tmp[2]=(byte)(sidlen>>>8);
tmp[3]=(byte)(sidlen);
System.arraycopy(sid, 0, tmp, 4, sidlen);
System.arraycopy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5);
byte[] signature=identity.getSignature(tmp);
if(signature==null){ // for example, too long key length.
break;
}
buf.putString(signature);
session.write(packet);
loop2:
while(true){
buf=session.read(buf);
command=buf.getCommand()&0xff;
if(command==SSH_MSG_USERAUTH_SUCCESS){
return true;
}
else if(command==SSH_MSG_USERAUTH_BANNER){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] _message=buf.getString();
byte[] lang=buf.getString();
String message=Util.byte2str(_message);
if(userinfo!=null){
userinfo.showMessage(message);
}
continue loop2;
}
else if(command==SSH_MSG_USERAUTH_FAILURE){
buf.getInt(); buf.getByte(); buf.getByte();
byte[] foo=buf.getString();
int partial_success=buf.getByte();
//System.err.println(new String(foo)+
// " partial_success:"+(partial_success!=0));
if(partial_success!=0){
throw new JSchPartialAuthException(Util.byte2str(foo));
}
session.auth_failures++;
break;
}
//System.err.println("USERAUTH fail ("+command+")");
//throw new JSchException("USERAUTH fail ("+command+")");
break;
}
}
}
return false;
}
}

View File

@ -0,0 +1,39 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface UserInfo{
String getPassphrase();
String getPassword();
boolean promptPassword(String message);
boolean promptPassphrase(String message);
boolean promptYesNo(String message);
void showMessage(String message);
}

View File

@ -0,0 +1,510 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.net.Socket;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
class Util{
private static final byte[] b64 =Util.str2byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
private static byte val(byte foo){
if(foo == '=') return 0;
for(int j=0; j<b64.length; j++){
if(foo==b64[j]) return (byte)j;
}
return 0;
}
static byte[] fromBase64(byte[] buf, int start, int length){
byte[] foo=new byte[length];
int j=0;
for (int i=start;i<start+length;i+=4){
foo[j]=(byte)((val(buf[i])<<2)|((val(buf[i+1])&0x30)>>>4));
if(buf[i+2]==(byte)'='){ j++; break;}
foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2));
if(buf[i+3]==(byte)'='){ j+=2; break;}
foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f));
j+=3;
}
byte[] bar=new byte[j];
System.arraycopy(foo, 0, bar, 0, j);
return bar;
}
static byte[] toBase64(byte[] buf, int start, int length){
byte[] tmp=new byte[length*2];
int i,j,k;
int foo=(length/3)*3+start;
i=0;
for(j=start; j<foo; j+=3){
k=(buf[j]>>>2)&0x3f;
tmp[i++]=b64[k];
k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f;
tmp[i++]=b64[k];
k=(buf[j+1]&0x0f)<<2|(buf[j+2]>>>6)&0x03;
tmp[i++]=b64[k];
k=buf[j+2]&0x3f;
tmp[i++]=b64[k];
}
foo=(start+length)-foo;
if(foo==1){
k=(buf[j]>>>2)&0x3f;
tmp[i++]=b64[k];
k=((buf[j]&0x03)<<4)&0x3f;
tmp[i++]=b64[k];
tmp[i++]=(byte)'=';
tmp[i++]=(byte)'=';
}
else if(foo==2){
k=(buf[j]>>>2)&0x3f;
tmp[i++]=b64[k];
k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f;
tmp[i++]=b64[k];
k=((buf[j+1]&0x0f)<<2)&0x3f;
tmp[i++]=b64[k];
tmp[i++]=(byte)'=';
}
byte[] bar=new byte[i];
System.arraycopy(tmp, 0, bar, 0, i);
return bar;
// return sun.misc.BASE64Encoder().encode(buf);
}
static String[] split(String foo, String split){
if(foo==null)
return null;
byte[] buf=Util.str2byte(foo);
java.util.Vector bar=new java.util.Vector();
int start=0;
int index;
while(true){
index=foo.indexOf(split, start);
if(index>=0){
bar.addElement(Util.byte2str(buf, start, index-start));
start=index+1;
continue;
}
bar.addElement(Util.byte2str(buf, start, buf.length-start));
break;
}
String[] result=new String[bar.size()];
for(int i=0; i<result.length; i++){
result[i]=(String)(bar.elementAt(i));
}
return result;
}
static boolean glob(byte[] pattern, byte[] name){
return glob0(pattern, 0, name, 0);
}
static private boolean glob0(byte[] pattern, int pattern_index,
byte[] name, int name_index){
if(name.length>0 && name[0]=='.'){
if(pattern.length>0 && pattern[0]=='.'){
if(pattern.length==2 && pattern[1]=='*') return true;
return glob(pattern, pattern_index+1, name, name_index+1);
}
return false;
}
return glob(pattern, pattern_index, name, name_index);
}
static private boolean glob(byte[] pattern, int pattern_index,
byte[] name, int name_index){
//System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", "+name_index);
int patternlen=pattern.length;
if(patternlen==0)
return false;
int namelen=name.length;
int i=pattern_index;
int j=name_index;
while(i<patternlen && j<namelen){
if(pattern[i]=='\\'){
if(i+1==patternlen)
return false;
i++;
if(pattern[i]!=name[j])
return false;
i+=skipUTF8Char(pattern[i]);
j+=skipUTF8Char(name[j]);
continue;
}
if(pattern[i]=='*'){
while(i<patternlen){
if(pattern[i]=='*'){
i++;
continue;
}
break;
}
if(patternlen==i)
return true;
byte foo=pattern[i];
if(foo=='?'){
while(j<namelen){
if(glob(pattern, i, name, j)){
return true;
}
j+=skipUTF8Char(name[j]);
}
return false;
}
else if(foo=='\\'){
if(i+1==patternlen)
return false;
i++;
foo=pattern[i];
while(j<namelen){
if(foo==name[j]){
if(glob(pattern, i+skipUTF8Char(foo),
name, j+skipUTF8Char(name[j]))){
return true;
}
}
j+=skipUTF8Char(name[j]);
}
return false;
}
while(j<namelen){
if(foo==name[j]){
if(glob(pattern, i, name, j)){
return true;
}
}
j+=skipUTF8Char(name[j]);
}
return false;
}
if(pattern[i]=='?'){
i++;
j+=skipUTF8Char(name[j]);
continue;
}
if(pattern[i]!=name[j])
return false;
i+=skipUTF8Char(pattern[i]);
j+=skipUTF8Char(name[j]);
if(!(j<namelen)){ // name is end
if(!(i<patternlen)){ // pattern is end
return true;
}
if(pattern[i]=='*'){
break;
}
}
continue;
}
if(i==patternlen && j==namelen)
return true;
if(!(j<namelen) && // name is end
pattern[i]=='*'){
boolean ok=true;
while(i<patternlen){
if(pattern[i++]!='*'){
ok=false;
break;
}
}
return ok;
}
return false;
}
static String quote(String path){
byte[] _path=str2byte(path);
int count=0;
for(int i=0;i<_path.length; i++){
byte b=_path[i];
if(b=='\\' || b=='?' || b=='*')
count++;
}
if(count==0)
return path;
byte[] _path2=new byte[_path.length+count];
for(int i=0, j=0; i<_path.length; i++){
byte b=_path[i];
if(b=='\\' || b=='?' || b=='*'){
_path2[j++]='\\';
}
_path2[j++]=b;
}
return byte2str(_path2);
}
static String unquote(String path){
byte[] foo=str2byte(path);
byte[] bar=unquote(foo);
if(foo.length==bar.length)
return path;
return byte2str(bar);
}
static byte[] unquote(byte[] path){
int pathlen=path.length;
int i=0;
while(i<pathlen){
if(path[i]=='\\'){
if(i+1==pathlen)
break;
System.arraycopy(path, i+1, path, i, path.length-(i+1));
pathlen--;
i++;
continue;
}
i++;
}
if(pathlen==path.length)
return path;
byte[] foo=new byte[pathlen];
System.arraycopy(path, 0, foo, 0, pathlen);
return foo;
}
private static String[] chars={
"0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
};
static String getFingerPrint(HASH hash, byte[] data){
try{
hash.init();
hash.update(data, 0, data.length);
byte[] foo=hash.digest();
StringBuffer sb=new StringBuffer();
int bar;
for(int i=0; i<foo.length;i++){
bar=foo[i]&0xff;
sb.append(chars[(bar>>>4)&0xf]);
sb.append(chars[(bar)&0xf]);
if(i+1<foo.length)
sb.append(":");
}
return sb.toString();
}
catch(Exception e){
return "???";
}
}
static boolean array_equals(byte[] foo, byte bar[]){
int i=foo.length;
if(i!=bar.length) return false;
for(int j=0; j<i; j++){ if(foo[j]!=bar[j]) return false; }
//try{while(true){i--; if(foo[i]!=bar[i])return false;}}catch(Exception e){}
return true;
}
static Socket createSocket(String host, int port, int timeout) throws JSchException{
Socket socket=null;
if(timeout==0){
try{
socket=new Socket(host, port);
return socket;
}
catch(Exception e){
String message=e.toString();
if(e instanceof Throwable)
throw new JSchException(message, (Throwable)e);
throw new JSchException(message);
}
}
final String _host=host;
final int _port=port;
final Socket[] sockp=new Socket[1];
final Exception[] ee=new Exception[1];
String message="";
Thread tmp=new Thread(new Runnable(){
public void run(){
sockp[0]=null;
try{
sockp[0]=new Socket(_host, _port);
}
catch(Exception e){
ee[0]=e;
if(sockp[0]!=null && sockp[0].isConnected()){
try{
sockp[0].close();
}
catch(Exception eee){}
}
sockp[0]=null;
}
}
});
tmp.setName("Opening Socket "+host);
tmp.start();
try{
tmp.join(timeout);
message="timeout: ";
}
catch(java.lang.InterruptedException eee){
}
if(sockp[0]!=null && sockp[0].isConnected()){
socket=sockp[0];
}
else{
message+="socket is not established";
if(ee[0]!=null){
message=ee[0].toString();
}
tmp.interrupt();
tmp=null;
throw new JSchException(message);
}
return socket;
}
static byte[] str2byte(String str, String encoding){
if(str==null)
return null;
try{ return str.getBytes(encoding); }
catch(java.io.UnsupportedEncodingException e){
return str.getBytes();
}
}
static byte[] str2byte(String str){
return str2byte(str, "UTF-8");
}
static String byte2str(byte[] str, String encoding){
return byte2str(str, 0, str.length, encoding);
}
static String byte2str(byte[] str, int s, int l, String encoding){
try{ return new String(str, s, l, encoding); }
catch(java.io.UnsupportedEncodingException e){
return new String(str, s, l);
}
}
static String byte2str(byte[] str){
return byte2str(str, 0, str.length, "UTF-8");
}
static String byte2str(byte[] str, int s, int l){
return byte2str(str, s, l, "UTF-8");
}
static final byte[] empty = str2byte("");
/*
static byte[] char2byte(char[] foo){
int len=0;
for(int i=0; i<foo.length; i++){
if((foo[i]&0xff00)==0) len++;
else len+=2;
}
byte[] bar=new byte[len];
for(int i=0, j=0; i<foo.length; i++){
if((foo[i]&0xff00)==0){
bar[j++]=(byte)foo[i];
}
else{
bar[j++]=(byte)(foo[i]>>>8);
bar[j++]=(byte)foo[i];
}
}
return bar;
}
*/
static void bzero(byte[] foo){
if(foo==null)
return;
for(int i=0; i<foo.length; i++)
foo[i]=0;
}
static String diffString(String str, String[] not_available){
String[] stra=Util.split(str, ",");
String result=null;
loop:
for(int i=0; i<stra.length; i++){
for(int j=0; j<not_available.length; j++){
if(stra[i].equals(not_available[j])){
continue loop;
}
}
if(result==null){ result=stra[i]; }
else{ result=result+","+stra[i]; }
}
return result;
}
static String checkTilde(String str){
if(str.indexOf("~") != -1){
try {
str = str.replace("~", System.getProperty("user.home"));
}
catch(SecurityException e){
}
}
return str;
}
private static int skipUTF8Char(byte b){
if((byte)(b&0x80)==0) return 1;
if((byte)(b&0xe0)==(byte)0xc0) return 2;
if((byte)(b&0xf0)==(byte)0xe0) return 3;
return 1;
}
static byte[] fromFile(String _file) throws IOException {
_file = checkTilde(_file);
File file = new File(_file);
FileInputStream fis = new FileInputStream(_file);
try {
byte[] result = new byte[(int)(file.length())];
int len=0;
while(true){
int i=fis.read(result, len, result.length-len);
if(i<=0)
break;
len+=i;
}
fis.close();
return result;
}
finally {
if(fis!=null)
fis.close();
}
}
}

View File

@ -0,0 +1,73 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES128CBC implements Cipher{
private static final int ivsize=16;
private static final int bsize=16;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return true; }
}

View File

@ -0,0 +1,73 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES128CTR implements Cipher{
private static final int ivsize=16;
private static final int bsize=16;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES192CBC implements Cipher{
private static final int ivsize=16;
private static final int bsize=24;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return true; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES192CTR implements Cipher{
private static final int ivsize=16;
private static final int bsize=24;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES256CBC implements Cipher{
private static final int ivsize=16;
private static final int bsize=32;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return true; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.spec.*;
public class AES256CTR implements Cipher{
private static final int ivsize=16;
private static final int bsize=32;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(iv.length>ivsize){
tmp=new byte[ivsize];
System.arraycopy(iv, 0, tmp, 0, tmp.length);
iv=tmp;
}
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv));
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,68 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.*;
import javax.crypto.spec.*;
public class ARCFOUR implements Cipher{
private static final int ivsize=8;
private static final int bsize=16;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
String pad="NoPadding";
byte[] tmp;
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
cipher=javax.crypto.Cipher.getInstance("RC4");
SecretKeySpec _key = new SecretKeySpec(key, "RC4");
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
_key);
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.*;
import javax.crypto.spec.*;
public class ARCFOUR128 implements Cipher{
private static final int ivsize=8;
private static final int bsize=16;
private static final int skip=1536;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
byte[] tmp;
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
cipher=javax.crypto.Cipher.getInstance("RC4");
SecretKeySpec _key = new SecretKeySpec(key, "RC4");
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
_key);
byte[] foo=new byte[1];
for(int i=0; i<skip; i++){
cipher.update(foo, 0, 1, foo, 0);
}
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

View File

@ -0,0 +1,71 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch.jce;
import com.jcraft.jsch.Cipher;
import javax.crypto.*;
import javax.crypto.spec.*;
public class ARCFOUR256 implements Cipher{
private static final int ivsize=8;
private static final int bsize=32;
private static final int skip=1536;
private javax.crypto.Cipher cipher;
public int getIVSize(){return ivsize;}
public int getBlockSize(){return bsize;}
public void init(int mode, byte[] key, byte[] iv) throws Exception{
byte[] tmp;
if(key.length>bsize){
tmp=new byte[bsize];
System.arraycopy(key, 0, tmp, 0, tmp.length);
key=tmp;
}
try{
cipher=javax.crypto.Cipher.getInstance("RC4");
SecretKeySpec _key = new SecretKeySpec(key, "RC4");
cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE),
_key);
byte[] foo=new byte[1];
for(int i=0; i<skip; i++){
cipher.update(foo, 0, 1, foo, 0);
}
}
catch(Exception e){
cipher=null;
throw e;
}
}
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
cipher.update(foo, s1, len, bar, s2);
}
public boolean isCBC(){return false; }
}

Some files were not shown because too many files have changed in this diff Show More