Author: toad
Date: 2008-12-02 18:51:25 +0000 (Tue, 02 Dec 2008)
New Revision: 24014
Modified:
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/PacketTracker.java
trunk/freenet/src/freenet/node/PeerNode.java
Log:
New negotiation type 3. If we connect with neg type 3, we don't change the
PacketTracker on rekeying.
Should help a lot with bug #2692.
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2008-12-02
13:55:19 UTC (rev 24013)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2008-12-02
18:51:25 UTC (rev 24014)
@@ -533,7 +533,7 @@
Logger.error(this, "Decrypted auth packet but invalid
version: "+version);
return;
}
- if(negType != 2) {
+ if(!(negType == 2 || negType == 3)) {
Logger.error(this, "Unknown neg type: "+negType);
return;
}
@@ -549,10 +549,10 @@
if(packetType == 0) {
// Phase 1
- processJFKMessage1(payload,4,null,replyTo, true,
setupType);
+ processJFKMessage1(payload,4,null,replyTo, true,
setupType, negType);
} else if(packetType == 2) {
// Phase 3
- processJFKMessage3(payload, 4, null, replyTo, false,
true, setupType);
+ processJFKMessage3(payload, 4, null, replyTo, false,
true, setupType, negType);
} else {
Logger.error(this, "Invalid phase "+packetType+" for
anonymous-initiator (we are the responder)");
}
@@ -577,7 +577,7 @@
Logger.error(this, "Decrypted auth packet but invalid
version: "+version);
return;
}
- if(negType != 2) {
+ if(!(negType == 2 || negType == 3)) {
Logger.error(this, "Unknown neg type: "+negType);
return;
}
@@ -593,10 +593,10 @@
if(packetType == 1) {
// Phase 2
- processJFKMessage2(payload, 4, pn, replyTo, true,
setupType);
+ processJFKMessage2(payload, 4, pn, replyTo, true,
setupType, negType);
} else if(packetType == 3) {
// Phase 4
- processJFKMessage4(payload, 4, pn, replyTo, false,
true, setupType);
+ processJFKMessage4(payload, 4, pn, replyTo, false,
true, setupType, negType);
} else {
Logger.error(this, "Invalid phase "+packetType+" for
anonymous-initiator (we are the responder)");
}
@@ -642,7 +642,7 @@
} else if (negType == 1) {
Logger.error(this, "Old StationToStation (negType 1)
not supported.");
return;
- } else if (negType==2){
+ } else if (negType==2 || negType == 3){ // negType == 3 => no
new PacketTracker when rekeying
/*
* We implement Just Fast Keying key management
protocol with active identity protection
* for the initiator and no identity protection for the
responder
@@ -673,7 +673,7 @@
* session key will be different,can be used to
differentiate between
* parallel sessions
*/
-
processJFKMessage1(payload,3,pn,replyTo,false,-1);
+
processJFKMessage1(payload,3,pn,replyTo,false,-1,negType);
}
else if(packetType==1){
@@ -682,7 +682,7 @@
* nonce and an authenticator calculated from a
transient hash key private
* to the responder.
*/
-
processJFKMessage2(payload,3,pn,replyTo,false,-1);
+
processJFKMessage2(payload,3,pn,replyTo,false,-1,negType);
}
else if(packetType==2){
/*
@@ -690,7 +690,7 @@
* cached by the Responder.Receiving a
duplicate message simply causes
* the responder to Re-transmit the
corresponding message4
*/
- processJFKMessage3(payload, 3, pn, replyTo,
oldOpennetPeer, false, -1);
+ processJFKMessage3(payload, 3, pn, replyTo,
oldOpennetPeer, false, -1, negType);
}
else if(packetType==3){
/*
@@ -698,7 +698,7 @@
* using the same keys as in the previous
message.
* The signature is non-message recovering
*/
- processJFKMessage4(payload, 3, pn, replyTo,
oldOpennetPeer, false, -1);
+ processJFKMessage4(payload, 3, pn, replyTo,
oldOpennetPeer, false, -1, negType);
}
} else {
Logger.error(this, "Decrypted auth packet but unknown
negotiation type "+negType+" from "+replyTo+" possibly from "+pn);
@@ -729,7 +729,7 @@
* ACM Transactions on Information and System Security, Vol 7 No 2, May
2004, Pages 1-30.
*
*/
- private void processJFKMessage1(byte[] payload,int offset,PeerNode
pn,Peer replyTo, boolean unknownInitiator, int setupType)
+ private void processJFKMessage1(byte[] payload,int offset,PeerNode
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType)
{
long t1=System.currentTimeMillis();
if(logMINOR) Logger.minor(this, "Got a JFK(1) message,
processing it - "+pn);
@@ -760,7 +760,7 @@
NativeBigInteger _hisExponential = new
NativeBigInteger(1,hisExponential);
if(DiffieHellman.checkDHExponentialValidity(this.getClass(),
_hisExponential)) {
- sendJFKMessage2(nonceInitiator, hisExponential, pn,
replyTo, unknownInitiator, setupType);
+ sendJFKMessage2(nonceInitiator, hisExponential, pn,
replyTo, unknownInitiator, setupType, negType);
}else
Logger.error(this, "We can't accept the exponential
"+pn+" sent us!! REDFLAG: IT CAN'T HAPPEN UNLESS AGAINST AN ACTIVE ATTACKER!!");
@@ -777,7 +777,7 @@
* know the responder in all cases.
* @param replyTo The peer to send the actual packet to.
*/
- private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean
unknownInitiator, int setupType) {
+ private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean
unknownInitiator, int setupType, int negType) {
if(logMINOR) Logger.minor(this, "Sending a JFK(1) message to
"+replyTo+" for "+pn.getPeer());
final long now = System.currentTimeMillis();
DiffieHellmanLightContext ctx = (DiffieHellmanLightContext)
pn.getKeyAgreementSchemeContext();
@@ -804,9 +804,9 @@
if(unknownInitiator) {
offset += modulusLength;
System.arraycopy(pn.identityHash, 0, message1, offset,
pn.identityHash.length);
-
sendAnonAuthPacket(1,2,0,setupType,message1,pn,replyTo,pn.anonymousInitiatorSetupCipher);
+
sendAnonAuthPacket(1,negType,0,setupType,message1,pn,replyTo,pn.anonymousInitiatorSetupCipher);
} else {
- sendAuthPacket(1,2,0,message1,pn,replyTo);
+ sendAuthPacket(1,negType,0,message1,pn,replyTo);
}
long t2=System.currentTimeMillis();
if((t2-now)>500)
@@ -824,7 +824,7 @@
* @param pn The node to encrypt the message for. CAN BE NULL if
anonymous-initiator.
* @param replyTo The peer to send the packet to.
*/
- private void sendJFKMessage2(byte[] nonceInitator, byte[]
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int
setupType) {
+ private void sendJFKMessage2(byte[] nonceInitator, byte[]
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int
setupType, int negType) {
if(logMINOR) Logger.minor(this, "Sending a JFK(2) message to
"+pn);
DiffieHellmanLightContext ctx = getLightDiffieHellmanContext();
// g^r
@@ -857,9 +857,9 @@
System.arraycopy(authenticator, 0, message2, offset,
HASH_LENGTH);
if(unknownInitiator)
-
sendAnonAuthPacket(1,2,1,setupType,message2,pn,replyTo,crypto.anonSetupCipher);
+
sendAnonAuthPacket(1,negType,1,setupType,message2,pn,replyTo,crypto.anonSetupCipher);
else
- sendAuthPacket(1,2,1,message2,pn,replyTo);
+ sendAuthPacket(1,negType,1,message2,pn,replyTo);
}
/*
@@ -896,7 +896,7 @@
* @param pn The peerNode we are talking to. Cannot be null as we are
the initiator.
*/
- private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode
pn,Peer replyTo, boolean unknownInitiator, int setupType)
+ private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType)
{
long t1=System.currentTimeMillis();
if(logMINOR) Logger.minor(this, "Got a JFK(2) message,
processing it - "+pn.getPeer());
@@ -939,7 +939,7 @@
}
if(message3 != null) {
Logger.normal(this, "We replayed a message from the
cache (shouldn't happen often) - "+pn.getPeer());
- sendAuthPacket(1, 2, 3, (byte[]) message3, pn, replyTo);
+ sendAuthPacket(1, negType, 3, (byte[]) message3, pn,
replyTo);
return;
}
@@ -977,7 +977,7 @@
// At this point we know it's from the peer, so we can report a
packet received.
pn.receivedPacket(true, false);
- sendJFKMessage3(1, 2, 3, nonceInitiator, nonceResponder,
hisExponential, authenticator, pn, replyTo, unknownInitiator, setupType);
+ sendJFKMessage3(1, negType, 3, nonceInitiator, nonceResponder,
hisExponential, authenticator, pn, replyTo, unknownInitiator, setupType);
long t2=System.currentTimeMillis();
if((t2-t1)>500)
@@ -1008,7 +1008,7 @@
* responder.
* @return byte Message3
*/
- private void processJFKMessage3(byte[] payload, int inputOffset,
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int
setupType)
+ private void processJFKMessage3(byte[] payload, int inputOffset,
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int
setupType, int negType)
{
final long t1 = System.currentTimeMillis();
if(logMINOR) Logger.minor(this, "Got a JFK(3) message,
processing it - "+pn);
@@ -1071,9 +1071,9 @@
// We are replaying a JFK(4).
// Therefore if it is anon-initiator it is encrypted
with our setup key.
if(unknownInitiator)
- sendAnonAuthPacket(1,2,3,setupType, (byte[])
message4, null, replyTo, crypto.anonSetupCipher);
+ sendAnonAuthPacket(1,negType,3,setupType,
(byte[]) message4, null, replyTo, crypto.anonSetupCipher);
else
- sendAuthPacket(1, 2, 3, (byte[]) message4, pn,
replyTo);
+ sendAuthPacket(1, negType, 3, (byte[])
message4, pn, replyTo);
return;
} else {
if(logDEBUG) Logger.debug(this, "No message4 found for
"+HexUtil.bytesToHex(authenticator)+" responderExponential
"+Fields.hashCode(responderExponential)+" initiatorExponential
"+Fields.hashCode(initiatorExponential)+" nonceResponder
"+Fields.hashCode(nonceResponder)+" nonceInitiator
"+Fields.hashCode(nonceInitiator)+" address
"+HexUtil.bytesToHex(replyTo.getAddress().getAddress()));
@@ -1155,7 +1155,7 @@
pn.receivedPacket(true, false);
// Send reply
- sendJFKMessage4(1, 2, 3, nonceInitiator,
nonceResponder,initiatorExponential, responderExponential,
+ sendJFKMessage4(1, negType, 3, nonceInitiator,
nonceResponder,initiatorExponential, responderExponential,
c, Ke, Ka, authenticator, hisRef, pn, replyTo,
unknownInitiator, setupType);
c.initialize(Ks);
@@ -1175,7 +1175,7 @@
// wantPeer will call node.peers.addPeer(), we don't
have to.
}
- if(pn.completedHandshake(bootID, hisRef, 0, hisRef.length, c,
Ks, replyTo, true)) {
+ if(pn.completedHandshake(bootID, hisRef, 0, hisRef.length, c,
Ks, replyTo, true, negType)) {
if(dontWant)
node.peers.disconnect(pn, true, false);
else
@@ -1240,7 +1240,7 @@
* @param pn The PeerNode we are talking to. Cannot be null as we are
the initiator.
* @param replyTo The Peer we are replying to.
*/
- private boolean processJFKMessage4(byte[] payload, int inputOffset,
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator,
int setupType)
+ private boolean processJFKMessage4(byte[] payload, int inputOffset,
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator,
int setupType, int negType)
{
final long t1 = System.currentTimeMillis();
if(logMINOR) Logger.minor(this, "Got a JFK(4) message,
processing it - "+pn.getPeer());
@@ -1370,7 +1370,7 @@
// We change the key
c.initialize(pn.jfkKs);
- if(pn.completedHandshake(bootID, data, 8, data.length - 8, c,
pn.jfkKs, replyTo, false)) {
+ if(pn.completedHandshake(bootID, data, 8, data.length - 8, c,
pn.jfkKs, replyTo, false, negType)) {
if(dontWant)
node.peers.disconnect(pn, true, false);
else
@@ -1411,7 +1411,7 @@
* @param replyTo The Peer to send the packet to.
*/
- private void sendJFKMessage3(int version,int negType,int phase,byte[]
nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[]
authenticator, final PeerNode pn, final Peer replyTo, final boolean
unknownInitiator, final int setupType)
+ private void sendJFKMessage3(int version,final int negType,int
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[]
authenticator, final PeerNode pn, final Peer replyTo, final boolean
unknownInitiator, final int setupType)
{
if(logMINOR) Logger.minor(this, "Sending a JFK(3) message to
"+pn.getPeer());
long t1=System.currentTimeMillis();
@@ -1503,18 +1503,18 @@
authenticatorCache.put(new
ByteArrayWrapper(authenticator),message3);
}
if(unknownInitiator)
- sendAnonAuthPacket(1, 2, 2, setupType, message3, pn,
replyTo, pn.anonymousInitiatorSetupCipher);
+ sendAnonAuthPacket(1, negType, 2, setupType, message3,
pn, replyTo, pn.anonymousInitiatorSetupCipher);
else
- sendAuthPacket(1, 2, 2, message3, pn, replyTo);
+ sendAuthPacket(1, negType, 2, message3, pn, replyTo);
/* Re-send the packet after 5sec if we don't get any reply */
node.getTicker().queueTimedJob(new Runnable() {
public void run() {
if(pn.timeLastConnected() >=
pn.lastReceivedPacketTime()) {
if(unknownInitiator)
- sendAnonAuthPacket(1, 2, 2,
setupType, message3, pn, replyTo, pn.anonymousInitiatorSetupCipher);
+ sendAnonAuthPacket(1, negType,
2, setupType, message3, pn, replyTo, pn.anonymousInitiatorSetupCipher);
else
- sendAuthPacket(1, 2, 2,
message3, pn, replyTo);
+ sendAuthPacket(1, negType, 2,
message3, pn, replyTo);
}
}
}, 5*1000);
@@ -1599,9 +1599,9 @@
}
if(unknownInitiator)
- sendAnonAuthPacket(1, 2, 3, setupType, message4, pn,
replyTo, crypto.anonSetupCipher);
+ sendAnonAuthPacket(1, negType, 3, setupType, message4,
pn, replyTo, crypto.anonSetupCipher);
else
- sendAuthPacket(1, 2, 3, message4, pn, replyTo);
+ sendAuthPacket(1, negType, 3, message4, pn, replyTo);
long t2=System.currentTimeMillis();
if((t2-t1)>500)
Logger.error(this,"Message4 timeout error:Sending
packet for"+pn.getPeer());
@@ -2774,7 +2774,7 @@
pn.couldNotSendHandshake();
return;
}
- sendJFKMessage1(pn, peer, pn.handshakeUnknownInitiator(),
pn.handshakeSetupType());
+ sendJFKMessage1(pn, peer, pn.handshakeUnknownInitiator(),
pn.handshakeSetupType(), negType);
if(logMINOR)
Logger.minor(this, "Sending handshake to "+peer+" for
"+pn);
pn.sentHandshake();
@@ -2794,7 +2794,7 @@
}
public int[] supportedNegTypes() {
- return new int[] { 2 };
+ return new int[] { 2, 3 };
}
public int fullHeadersLengthOneMessage() {
Modified: trunk/freenet/src/freenet/node/PacketTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketTracker.java 2008-12-02 13:55:19 UTC
(rev 24013)
+++ trunk/freenet/src/freenet/node/PacketTracker.java 2008-12-02 18:51:25 UTC
(rev 24014)
@@ -107,6 +107,7 @@
*/
public void deprecated() {
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ if(logMINOR) Logger.minor(this, "Deprecated: "+this);
isDeprecated = true;
sentPacketsContents.interrupt();
}
@@ -1009,6 +1010,10 @@
* *** Must only be called if the KeyTracker is not to be kept.
Otherwise, we may receive some packets twice. ***
*/
public void completelyDeprecated(KeyTracker newTracker) {
+ if(newTracker.packets == this) {
+ Logger.error(this, "Completely deprecated in favour of
self!");
+ return;
+ }
if(logMINOR)
Logger.minor(this, "Completely deprecated: " + this + "
in favour of " + newTracker);
LimitedRangeIntByteArrayMapElement[] elements = clear();
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2008-12-02 13:55:19 UTC
(rev 24013)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2008-12-02 18:51:25 UTC
(rev 24014)
@@ -1805,7 +1805,7 @@
* @param replyTo The IP the handshake came in on.
* @return True unless we rejected the handshake, or it failed to parse.
*/
- public boolean completedHandshake(long thisBootID, byte[] data, int
offset, int length, BlockCipher encCipher, byte[] encKey, Peer replyTo, boolean
unverified) {
+ public boolean completedHandshake(long thisBootID, byte[] data, int
offset, int length, BlockCipher encCipher, byte[] encKey, Peer replyTo, boolean
unverified, int negType) {
logMINOR = Logger.shouldLog(Logger.MINOR, PeerNode.class);
long now = System.currentTimeMillis();
@@ -1852,15 +1852,13 @@
routable = false;
} else
older = false;
- PacketTracker packets = new PacketTracker(this);
- KeyTracker newTracker = new KeyTracker(this, packets,
encCipher, encKey);
- if(logMINOR) Logger.minor(this, "New key tracker in
completedHandshake: "+newTracker+" for "+shortToString());
changedIP(replyTo);
boolean bootIDChanged = false;
boolean wasARekey = false;
KeyTracker oldPrev = null;
KeyTracker oldCur = null;
KeyTracker prev = null;
+ KeyTracker newTracker;
MessageItem[] messagesTellDisconnected = null;
synchronized(this) {
handshakeCount = 0;
@@ -1887,7 +1885,11 @@
} else if(bootIDChanged && logMINOR)
Logger.minor(this, "Changed boot ID from " +
bootID + " to " + thisBootID + " for " + getPeer());
this.bootID = thisBootID;
+ PacketTracker packets;
+ boolean newPacketTracker = false;
if(bootIDChanged) {
+ packets = new PacketTracker(this);
+ newPacketTracker = true;
oldPrev = previousTracker;
oldCur = currentTracker;
previousTracker = null;
@@ -1897,7 +1899,22 @@
// connection initial messages by
maybeOnConnect().
messagesTellDisconnected =
grabQueuedMessageItems();
this.offeredMainJarVersion = 0;
- } // else it's a rekey
+ } else {
+ // else it's a rekey
+ if(currentTracker != null &&
currentTracker.packets.isDeprecated()) {
+ packets = new PacketTracker(this);
+ newPacketTracker = true;
+ } else if(currentTracker != null && negType >=
3)
+ packets = currentTracker.packets;
+ else if(previousTracker != null && negType >= 3)
+ packets = previousTracker.packets;
+ else {
+ packets = new PacketTracker(this);
+ newPacketTracker = true;
+ }
+ }
+ newTracker = new KeyTracker(this, packets, encCipher,
encKey);
+ if(logMINOR) Logger.minor(this, "New key tracker in
completedHandshake: "+newTracker+" for "+shortToString()+" neg type "+negType+"
new packet tracker: "+newPacketTracker);
if(unverified) {
if(unverifiedTracker != null) {
// Keep the old unverified tracker if
possible.
@@ -1941,11 +1958,11 @@
node.lm.lostOrRestartedNode(this);
node.usm.onRestart(this);
}
- if(oldPrev != null)
+ if(oldPrev != null && oldPrev.packets != newTracker.packets)
oldPrev.packets.completelyDeprecated(newTracker);
- if(oldCur != null)
+ if(oldCur != null && oldCur.packets != newTracker.packets)
oldCur.packets.completelyDeprecated(newTracker);
- if(prev != null)
+ if(prev != null && prev.packets != newTracker.packets)
prev.packets.deprecated();
PacketThrottle throttle;
synchronized(this) {
@@ -1979,6 +1996,7 @@
*/
private synchronized void maybeSwapTrackers() {
if(currentTracker == null || previousTracker == null) return;
+ if(currentTracker.packets == previousTracker.packets) return;
long delta = Math.abs(currentTracker.packets.createdTime -
previousTracker.packets.createdTime);
if(previousTracker != null &&
(!previousTracker.packets.isDeprecated()) &&
delta < CHECK_FOR_SWAPPED_TRACKERS_INTERVAL) {
@@ -2006,9 +2024,9 @@
KeyTracker temp = previousTracker;
previousTracker = currentTracker;
currentTracker = temp;
- if(logMINOR) Logger.minor(this, "Swapped
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker);
+ if(logMINOR) Logger.minor(this, "Swapped
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker+" delta
"+delta+" cur.deprecated="+currentTracker.packets.isDeprecated()+"
prev.deprecated="+previousTracker.packets.isDeprecated());
} else {
- if(logMINOR) Logger.minor(this, "Not swapping
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker);
+ if(logMINOR) Logger.minor(this, "Not swapping
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker+" delta
"+delta+" cur.deprecated="+currentTracker.packets.isDeprecated()+"
prev.deprecated="+previousTracker.packets.isDeprecated());
}
} else {
if (logMINOR)
@@ -2160,7 +2178,7 @@
peerAddedTime = 0; // don't store anymore
ctx = null;
maybeSwapTrackers();
- if(previousTracker != null)
+ if(previousTracker != null &&
previousTracker.packets != currentTracker.packets)
previousTracker.packets.deprecated();
} else
return;
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs