📄 sestsconnectionimpl.java
字号:
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: SESTSConnectionImpl.java
package org.gudy.azureus2.pluginsimpl.local.utils.security;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.security.*;
import com.aelitis.azureus.core.util.CopyOnWriteList;
import com.aelitis.azureus.core.util.bloom.BloomFilter;
import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.plugins.messaging.MessageException;
import org.gudy.azureus2.plugins.messaging.generic.*;
import org.gudy.azureus2.plugins.network.RateLimiter;
import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
import org.gudy.azureus2.plugins.utils.security.SEPublicKey;
import org.gudy.azureus2.plugins.utils.security.SEPublicKeyLocator;
import org.gudy.azureus2.pluginsimpl.local.messaging.GenericMessageConnectionImpl;
import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
// Referenced classes of package org.gudy.azureus2.pluginsimpl.local.utils.security:
// SEPublicKeyImpl
public class SESTSConnectionImpl
implements GenericMessageConnection
{
private static final int CRYPTO_SETUP_TIMEOUT = 60000;
private static final LogIDs LOGID;
private static final byte AES_IV1[] = {
21, -32, 107, 126, -104, 89, -28, -89, 52, 102,
-83, 72, 53, -30, -48, 36
};
private static final byte AES_IV2[] = {
-60, -17, 6, 60, -104, 35, -24, -76, 38, 88,
-82, -71, 44, 36, -74, 17
};
private final int AES_KEY_SIZE_BYTES;
private static long last_incoming_sts_create;
private static List connections = new ArrayList();
private static final int BLOOM_RECREATE = 30000;
private static final int BLOOM_INCREASE = 500;
private static BloomFilter generate_bloom = BloomFilterFactory.createAddRemove4Bit(500);
private static long generate_bloom_create_time = SystemTime.getCurrentTime();
private AzureusCore core;
private GenericMessageConnectionImpl connection;
private SEPublicKey my_public_key;
private SEPublicKeyLocator key_locator;
private String reason;
private int block_crypto;
private long create_time;
private CryptoSTSEngine sts_engine;
private CopyOnWriteList listeners;
private boolean sent_keys;
private boolean sent_auth;
private PooledByteBuffer pending_message;
private AESemaphore crypto_complete;
private Cipher outgoing_cipher;
private Cipher incoming_cipher;
private volatile boolean failed;
protected SESTSConnectionImpl(AzureusCore _core, GenericMessageConnectionImpl _connection, SEPublicKey _my_public_key, SEPublicKeyLocator _key_locator, String _reason, int _block_crypto)
throws Exception
{
AES_KEY_SIZE_BYTES = AES_IV1.length;
listeners = new CopyOnWriteList();
crypto_complete = new AESemaphore("SESTSConnection:send");
core = _core;
connection = _connection;
my_public_key = _my_public_key;
key_locator = _key_locator;
reason = _reason;
block_crypto = _block_crypto;
create_time = SystemTime.getCurrentTime();
synchronized (connections)
{
connections.add(this);
}
if (connection.isIncoming())
rateLimit(connection.getEndpoint().getNotionalAddress());
sts_engine = core.getCryptoManager().getECCHandler().getSTSEngine(reason);
connection.addListener(new GenericMessageConnectionListener() {
final SESTSConnectionImpl this$0;
public void connected(GenericMessageConnection connection)
{
reportConnected();
}
public void receive(GenericMessageConnection connection, PooledByteBuffer message)
throws MessageException
{
SESTSConnectionImpl.this.receive(message);
}
public void failed(GenericMessageConnection connection, Throwable error)
throws MessageException
{
reportFailed(error);
}
{
this$0 = SESTSConnectionImpl.this;
super();
}
});
}
protected int getConnectMethodCount()
{
return connection.getConnectMethodCount();
}
protected static void rateLimit(InetSocketAddress originator)
throws Exception
{
synchronized (org/gudy/azureus2/pluginsimpl/local/utils/security/SESTSConnectionImpl)
{
int hit_count = generate_bloom.add(originator.getAddress().getAddress());
long now = SystemTime.getCurrentTime();
if (generate_bloom.getSize() / generate_bloom.getEntryCount() < 10)
{
generate_bloom = BloomFilterFactory.createAddRemove4Bit(generate_bloom.getSize() + 500);
generate_bloom_create_time = now;
Logger.log(new LogEvent(LOGID, (new StringBuilder()).append("STS bloom: size increased to ").append(generate_bloom.getSize()).toString()));
} else
if (now < generate_bloom_create_time || now - generate_bloom_create_time > 30000L)
{
generate_bloom = BloomFilterFactory.createAddRemove4Bit(generate_bloom.getSize());
generate_bloom_create_time = now;
}
if (hit_count >= 15)
{
Logger.log(new LogEvent(LOGID, (new StringBuilder()).append("STS bloom: too many recent connection attempts from ").append(originator).toString()));
Debug.out((new StringBuilder()).append("STS: too many recent connection attempts from ").append(originator).toString());
throw new IOException("Too many recent connection attempts (sts)");
}
long since_last = now - last_incoming_sts_create;
long delay = 100L - since_last;
if (delay > 0L && delay < 100L)
try
{
Logger.log(new LogEvent(LOGID, (new StringBuilder()).append("STS: too many recent connection attempts, delaying ").append(delay).toString()));
Thread.sleep(delay);
}
catch (Throwable e) { }
last_incoming_sts_create = now;
}
}
public GenericMessageEndpoint getEndpoint()
{
return connection.getEndpoint();
}
public int getMaximumMessageSize()
{
int max = connection.getMaximumMessageSize();
if (outgoing_cipher != null)
max -= outgoing_cipher.getBlockSize();
return max;
}
public String getType()
{
String con_type = connection.getType();
if (con_type.length() == 0)
return "";
else
return (new StringBuilder()).append("AES ").append(con_type).toString();
}
public int getTransportType()
{
return connection.getTransportType();
}
public void addInboundRateLimiter(RateLimiter limiter)
{
connection.addInboundRateLimiter(limiter);
}
public void removeInboundRateLimiter(RateLimiter limiter)
{
connection.removeInboundRateLimiter(limiter);
}
public void addOutboundRateLimiter(RateLimiter limiter)
{
connection.addOutboundRateLimiter(limiter);
}
public void removeOutboundRateLimiter(RateLimiter limiter)
{
connection.removeOutboundRateLimiter(limiter);
}
public void connect()
throws MessageException
{
if (connection.isIncoming())
connection.connect();
else
try
{
ByteBuffer buffer = ByteBuffer.allocate(32768);
sts_engine.getKeys(buffer);
buffer.flip();
sent_keys = true;
connection.connect(buffer);
}
catch (CryptoManagerException e)
{
throw new MessageException("Failed to get initial keys", e);
}
}
protected void setFailed()
{
failed = true;
try
{
cryptoComplete();
}
catch (Throwable e)
{
Debug.printStackTrace(e);
}
}
public void receive(PooledByteBuffer message)
throws MessageException
{
try
{
boolean forward = false;
boolean crypto_completed = false;
ByteBuffer out_buffer = null;
synchronized (this)
{
if (crypto_complete.isReleasedForever())
{
forward = true;
} else
{
ByteBuffer in_buffer = ByteBuffer.wrap(message.toByteArray());
message.returnToPool();
if (!sent_keys)
{
out_buffer = ByteBuffer.allocate(0x10000);
sts_engine.getKeys(out_buffer);
sent_keys = true;
sts_engine.putKeys(in_buffer);
sts_engine.getAuth(out_buffer);
sent_auth = true;
} else
if (!sent_auth)
{
out_buffer = ByteBuffer.allocate(0x10000);
sts_engine.putKeys(in_buffer);
sts_engine.getAuth(out_buffer);
sent_auth = true;
sts_engine.putAuth(in_buffer);
byte rem_key[] = sts_engine.getRemotePublicKey();
if (!key_locator.accept(this, new SEPublicKeyImpl(my_public_key.getType(), rem_key)))
throw new MessageException("remote public key not accepted");
setupBlockCrypto();
if (pending_message != null)
{
byte pending_bytes[] = pending_message.toByteArray();
int pending_size = pending_bytes.length;
if (outgoing_cipher != null)
{
pending_size = (((pending_size + AES_KEY_SIZE_BYTES) - 1) / AES_KEY_SIZE_BYTES) * AES_KEY_SIZE_BYTES;
if (pending_size == 0)
pending_size = AES_KEY_SIZE_BYTES;
}
if (out_buffer.remaining() >= pending_size)
{
if (outgoing_cipher != null)
out_buffer.put(outgoing_cipher.doFinal(pending_bytes));
else
out_buffer.put(pending_bytes);
pending_message = null;
}
}
crypto_completed = true;
} else
{
sts_engine.putAuth(in_buffer);
byte rem_key[] = sts_engine.getRemotePublicKey();
if (!key_locator.accept(this, new SEPublicKeyImpl(my_public_key.getType(), rem_key)))
{
connection.closing();
throw new MessageException("remote public key not accepted");
}
setupBlockCrypto();
crypto_completed = true;
if (in_buffer.hasRemaining())
{
message = new PooledByteBufferImpl(new DirectByteBuffer(in_buffer.slice()));
forward = true;
}
}
}
}
if (out_buffer != null)
{
out_buffer.flip();
connection.send(new PooledByteBufferImpl(new DirectByteBuffer(out_buffer)));
}
if (crypto_completed)
cryptoComplete();
if (forward)
receiveContent(message);
}
catch (Throwable e)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -