parsing of events; check that the persona in the results matches the destination

pull/4/head
Zlatin Balevsky 2019-05-24 21:35:29 +01:00
parent 5df170f982
commit ac889b7906
5 changed files with 76 additions and 5 deletions

View File

@ -188,6 +188,8 @@ class ConnectionAcceptor {
throw new IOException("invalid request header")
Persona sender = new Persona(dis)
if (sender.destination != e.getDestination())
throw new IOException("Sender destination mismatch expected $e.getDestination(), got $sender.destination")
int nResults = dis.readUnsignedShort()
for (int i = 0; i < nResults; i++) {
int jsonSize = dis.readUnsignedShort()

View File

@ -1,9 +1,54 @@
package com.muwire.core.search
import javax.naming.directory.InvalidSearchControlsException
import com.muwire.core.InfoHash
import com.muwire.core.Persona
import com.muwire.core.util.DataUtil
import net.i2p.data.Base64
class ResultsParser {
public static UIResultEvent parse(Persona p, def json) throws InvalidSearchResultException {
null
if (json.type != "Result")
throw new InvalidSearchResultException("not a result json")
if (json.version != 1)
throw new InvalidSearchResultException("unknown version $json.version")
if (json.name == null)
throw new InvalidSearchResultException("name missing")
if (json.size == null)
throw new InvalidSearchResultException("length missing")
if (json.infohash == null)
throw new InvalidSearchResultException("infohash missing")
if (json.pieceSize == null)
throw new InvalidSearchResultException("pieceSize missing")
if (!(json.hashList instanceof List))
throw new InvalidSearchResultException("hashlist not a list")
try {
String name = DataUtil.readi18nString(Base64.decode(json.name))
long size = Long.parseLong(json.size)
byte [] infoHash = Base64.decode(json.infohash)
if (infoHash.length != InfoHash.SIZE)
throw new InvalidSearchResultException("invalid infohash size $infoHash.length")
int pieceSize = Integer.parseInt(json.pieceSize)
byte [] hashList = new byte[json.hashList.size() * InfoHash.SIZE]
json.hashList.eachWithIndex { string, index ->
byte [] hashPiece = Base64.decode(string)
if (hashPiece.length != InfoHash.SIZE)
throw new InvalidSearchResultException("Invalid piece hash size $hashPiece.length at index $index")
System.arraycopy(hashPiece, 0, hashList, index * InfoHash.SIZE, InfoHash.SIZE)
}
InfoHash parsedIH = InfoHash.fromHashList(hashList)
if (parsedIH.getRoot() != infoHash)
throw new InvalidSearchControlsException("infohash root doesn't match")
return new UIResultEvent( sender : p,
name : name,
size : size,
infohash : parsedIH,
pieceSize : pieceSize)
} catch (Exception e) {
throw new InvalidSearchResultException("parsing search result failed",e)
}
}
}

View File

@ -48,9 +48,16 @@ class ResultsSender {
void sendResults(UUID uuid, SharedFile[] results, Destination target) {
log.info("Sending $results.length results for uuid $uuid to ${target.toBase32()}")
if (target.equals(me.destination)) {
def resultEvent = new ResultsEvent( uuid : uuid, results : results )
def uiResultEvent = new UIResultEvent(sender: me, resultsEvent : resultEvent)
eventBus.publish(uiResultEvent)
results.each {
long length = it.getFile().length()
def uiResultEvent = new UIResultEvent( sender : me,
name : it.getFile().getName(),
size : length,
infohash : it.getInfoHash(),
pieceSize : FileHasher.getPieceSize(length)
)
eventBus.publish(uiResultEvent)
}
} else {
executor.execute(new ResultSendJob(uuid : uuid, results : results, target: target))
}

View File

@ -1,9 +1,13 @@
package com.muwire.core.search
import com.muwire.core.Event
import com.muwire.core.InfoHash
import com.muwire.core.Persona
class UIResultEvent extends Event {
Persona sender
ResultsEvent resultsEvent
String name
long size
InfoHash infohash
int pieceSize
}

View File

@ -1,5 +1,7 @@
package com.muwire.core.util
import java.nio.charset.StandardCharsets
class DataUtil {
private final static int MAX_SHORT = (0x1 << 16) - 1
@ -36,4 +38,15 @@ class DataUtil {
(((int)(header[1] & 0xFF) << 8)) |
((int)header[2] & 0xFF)
}
static String readi18nString(byte [] encoded) {
if (encoded.length < 2)
throw new IllegalArgumentException("encoding too short $encoded.length")
int length = ((encoded[0] & 0xFF) << 8) | (encoded[1] & 0xFF)
if (encoded.length != length + 2)
throw new IllegalArgumentException("encoding doesn't match length, expected $length found $encoded.length")
byte [] string = new byte[length]
System.arraycopy(encoded, 2, string, 0, length)
new String(string, StandardCharsets.UTF_8)
}
}