lint the json on update server startup

dbus-notify
Zlatin Balevsky 2022-02-22 17:01:59 +00:00
parent 901c626d0a
commit dbe909945f
No known key found for this signature in database
GPG Key ID: A72832072D525E41
1 changed files with 58 additions and 4 deletions

View File

@ -1,5 +1,8 @@
package com.muwire.update package com.muwire.update
import net.i2p.data.Base64
import net.i2p.util.VersionComparator
import java.util.logging.Level import java.util.logging.Level
import groovy.json.JsonSlurper import groovy.json.JsonSlurper
@ -42,6 +45,9 @@ class UpdateServer {
System.exit(1) System.exit(1)
} }
byte [] json = loadJson(update)
log.info("update.json sanity check passed")
Properties props = System.getProperties().clone() Properties props = System.getProperties().clone()
props["inbound.nickname"] = "MuWire UpdateServer" props["inbound.nickname"] = "MuWire UpdateServer"
def i2pPropsFile = new File(home, "i2p.properties") def i2pPropsFile = new File(home, "i2p.properties")
@ -51,19 +57,67 @@ class UpdateServer {
session = i2pClient.createSession(new FileInputStream(keyFile), props) session = i2pClient.createSession(new FileInputStream(keyFile), props)
myDest = session.getMyDestination() myDest = session.getMyDestination()
session.addMuxedSessionListener(new Listener(update), I2PSession.PROTO_DATAGRAM, I2PSession.PORT_ANY) session.addMuxedSessionListener(new Listener(json), I2PSession.PROTO_DATAGRAM, I2PSession.PORT_ANY)
session.connect() session.connect()
log.info("Connected, going to sleep") log.info("Connected, going to sleep")
while(true) while(true)
Thread.sleep(Integer.MAX_VALUE) Thread.sleep(Integer.MAX_VALUE)
} }
/** also performs sanity checks */
private static byte[] loadJson(File file) {
// 1. Check if valid json
JsonSlurper slurper = new JsonSlurper()
def parsed = slurper.parse(file)
// 2. check if version parses
if (VersionComparator.comp("0.0.0", (String)parsed.version) >= 0)
throw new Exception("version invalid ${parsed.version}")
// 3. check string fields
["signer","text"].each { checkString(parsed[it])}
// 4. check infohashes
["infoHash","exe","mac","appimage","appimage-aarch64"].each {checkInfoHash(parsed[it])}
// 5. check beta
if (parsed.beta != null) {
// 1. Version must be an integer
Integer.parseInt(parsed.beta.version)
// 2. text fields
["signer","text"].each {checkString(parsed.beta[it])}
// 3. infohashes
["exe","appimage","mac"].each {
if (parsed.beta[it] != null)
checkInfoHash(parsed.beta[it])
}
}
// if we got here we're good
file.bytes
}
private static void checkString(def obj) {
if (!(obj instanceof String))
throw new Exception("object not a string")
}
private static void checkInfoHash(def obj) {
String s = (String) obj
byte [] decoded = Base64.decode(s)
if (decoded.length != 32)
throw new Exception("invalid infohash")
}
static class Listener implements I2PSessionMuxedListener { static class Listener implements I2PSessionMuxedListener {
private final File json private final byte[] json
private final def slurper = new JsonSlurper() private final def slurper = new JsonSlurper()
Listener(File json) { Listener(byte[] json) {
this.json = json this.json = json
} }
@ -87,7 +141,7 @@ class UpdateServer {
log.info("Got an update ping from "+sender.toBase32() + " reported version "+payload?.myVersion) log.info("Got an update ping from "+sender.toBase32() + " reported version "+payload?.myVersion)
def maker = new I2PDatagramMaker(session) def maker = new I2PDatagramMaker(session)
def response = maker.makeI2PDatagram(json.bytes) def response = maker.makeI2PDatagram(json)
session.sendMessage(sender, response, I2PSession.PROTO_DATAGRAM, 0, 2) session.sendMessage(sender, response, I2PSession.PROTO_DATAGRAM, 0, 2)
} catch (Exception e) { } catch (Exception e) {
log.log(Level.WARNING, "exception responding to update request",e) log.log(Level.WARNING, "exception responding to update request",e)