Skip to content

Commit

Permalink
#265 change buffer_margin computation to be dynamic based upon the MA…
Browse files Browse the repository at this point in the history
…C to allow connections that advertise small maximum packet sizes.
  • Loading branch information
norrisjeremy committed Jan 11, 2023
1 parent 27442a8 commit b90b045
Show file tree
Hide file tree
Showing 17 changed files with 555 additions and 43 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@
<version>1.15</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/jcraft/jsch/Buffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,13 @@ byte getCommand(){
return buffer[5];
}

// Hardcode this since we can't use dynamic Session value
private static final int buffer_margin = 32 + // maximum padding length
64 + // maximum mac length
32; // margin for deflater; deflater may inflate data

void checkFreeSize(int n){
int size = index+n+Session.buffer_margin;
int size = index+n+buffer_margin;
if(buffer.length<size){
int i = buffer.length*2;
if(i<size) i = size;
Expand Down
47 changes: 29 additions & 18 deletions src/main/java/com/jcraft/jsch/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,15 @@ private synchronized void init() throws IOException{
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.");
try{
if(_buf.length-(14+0)-getSession().getBufferMargin()<=0){
buffer=null;
packet=null;
throw new IOException("failed to initialize the channel.");
}
}
catch(JSchException e){
throw new IOException("failed to initialize the channel.", e);
}

}
Expand All @@ -265,21 +270,27 @@ public void write(byte[] buf, int s, int l) throws IOException{

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;
try{
while(l>0){
int _l=l;
int buffer_margin=getSession().getBufferMargin();
if(l>_bufl-(14+dataLen)-buffer_margin){
_l=_bufl-(14+dataLen)-buffer_margin;
}

if(_l<=0){
flush();
continue;
}

System.arraycopy(buf, s, _buf, 14+dataLen, _l);
dataLen+=_l;
s+=_l;
l-=_l;
}

System.arraycopy(buf, s, _buf, 14+dataLen, _l);
dataLen+=_l;
s+=_l;
l-=_l;
}
catch(JSchException e){
throw new IOException(e.toString(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected Packet genChannelOpenPacket() {

Buffer buf = new Buffer(50 +
socketPath.length() +
Session.buffer_margin);
session.getBufferMargin());
Packet packet = new Packet(buf);
packet.reset();
buf.putByte((byte) SSH_MSG_CHANNEL_OPEN);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void run(){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
-_session.getBufferMargin()
);
if(i<=0){
eof();
Expand Down Expand Up @@ -154,7 +154,7 @@ public void setOutputStream(OutputStream out){
protected Packet genChannelOpenPacket(){
Buffer buf = new Buffer(50 + // 6 + 4*8 + 12
host.length() + originator_IP_address.length() +
Session.buffer_margin);
session.getBufferMargin());
Packet packet = new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ public void run(){
Packet packet=new Packet(buf);
int i=0;
try{
Session _session = getSession();
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
-_session.getBufferMargin()
);
if(i<=0){
eof();
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/jcraft/jsch/ChannelSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,15 @@ void run(){
Packet packet=new Packet(buf);
int i=-1;
try{
Session _session=getSession();
while(isConnected() &&
thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
-_session.getBufferMargin()
);
if(i==0)continue;
if(i==-1){
Expand All @@ -262,7 +263,7 @@ void run(){
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
_session.write(packet, this, i);
}
}
catch(Exception e){
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/com/jcraft/jsch/ChannelSftp.java
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,10 @@ public void _put(InputStream src, String dst,

boolean dontcopy=true;

int buffer_margin=session.getBufferMargin();
if(!dontcopy){ // This case will not work anymore.
data=new byte[obuf.buffer.length
-(5+13+21+handle.length+Session.buffer_margin
-(5+13+21+handle.length+buffer_margin
)
];
}
Expand All @@ -616,7 +617,7 @@ public void _put(InputStream src, String dst,
else{
data=obuf.buffer;
_s=5+13+21+handle.length;
_datalen=obuf.buffer.length-_s-Session.buffer_margin;
_datalen=obuf.buffer.length-_s-buffer_margin;
}

int bulk_requests = rq.size();
Expand Down Expand Up @@ -664,7 +665,7 @@ public void _put(InputStream src, String dst,
foo-=sendWRITE(handle, offset, data, 0, foo);
if(data!=obuf.buffer){
data=obuf.buffer;
_datalen=obuf.buffer.length-_s-Session.buffer_margin;
_datalen=obuf.buffer.length-_s-buffer_margin;
}
}
else {
Expand Down Expand Up @@ -2581,8 +2582,10 @@ private int sendWRITE(byte[] handle, long offset,
byte[] data, int start, int length) throws Exception{
int _length=length;
opacket.reset();
if(obuf.buffer.length<obuf.index+13+21+handle.length+length+Session.buffer_margin){
_length=obuf.buffer.length-(obuf.index+13+21+handle.length+Session.buffer_margin);
Session _session=getSession();
int buffer_margin=_session.getBufferMargin();
if(obuf.buffer.length<obuf.index+13+21+handle.length+length+buffer_margin){
_length=obuf.buffer.length-(obuf.index+13+21+handle.length+buffer_margin);
// System.err.println("_length="+_length+" length="+length);
}

Expand All @@ -2597,7 +2600,7 @@ private int sendWRITE(byte[] handle, long offset,
obuf.putInt(_length);
obuf.skip(_length);
}
getSession().write(opacket, this, 21+handle.length+_length+4);
_session.write(opacket, this, 21+handle.length+_length+4);
return _length;
}
private void sendREAD(byte[] handle, long offset, int length) throws Exception{
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/jcraft/jsch/ChannelX11.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,13 @@ void run(){
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);
buf.buffer.length-14-_session.getBufferMargin());
if(i<=0){
eof();
break;
Expand All @@ -171,7 +172,7 @@ void run(){
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
_session.write(packet, this, i);
}
}
catch(Exception e){
Expand Down
29 changes: 24 additions & 5 deletions src/main/java/com/jcraft/jsch/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,6 @@ public class Session{

SocketFactory socket_factory=null;

static final int buffer_margin = 32 + // maximum padding length
64 + // maximum mac length
32; // margin for deflater; deflater may inflate data

private Hashtable<String, String> config=null;

private Proxy proxy=null;
Expand Down Expand Up @@ -562,7 +558,7 @@ public void connect(int connectTimeout) throws JSchException{
if(isConnected){
String message = e.toString();
packet.reset();
buf.checkFreeSize(1+4*3+message.length()+2+buffer_margin);
buf.checkFreeSize(1+4*3+message.length()+2+getBufferMargin());
buf.putByte((byte)SSH_MSG_DISCONNECT);
buf.putInt(3);
buf.putString(Util.str2byte(message));
Expand Down Expand Up @@ -3287,4 +3283,27 @@ public Logger getLogger() {
public void setLogger(Logger logger) {
this.logger = logger;
}

int getBufferMargin() {
int buffer_margin = 32 + // maximum padding length
32; // margin for deflater; deflater may inflate data

Cipher _c2scipher = c2scipher;
MAC _c2smac = c2smac;

// maximum mac length
int mac_length = 20;
if (_c2scipher != null && (_c2scipher.isChaCha20() || _c2scipher.isAEAD())) {
if (_c2scipher.getTagSize() > mac_length) {
mac_length = _c2scipher.getTagSize();
}
} else if (_c2smac != null) {
if (_c2smac.getBlockSize() > mac_length) {
mac_length = _c2smac.getBlockSize();
}
}
buffer_margin += mac_length;

return buffer_margin;
}
}
Loading

0 comments on commit b90b045

Please sign in to comment.