certificate backend
This commit is contained in:
@ -10,17 +10,20 @@ import net.i2p.crypto.DSAEngine
|
||||
import net.i2p.data.Signature
|
||||
import net.i2p.data.SigningPrivateKey
|
||||
import net.i2p.data.SigningPublicKey
|
||||
import net.i2p.data.Base64
|
||||
|
||||
class Certificate {
|
||||
private final byte version
|
||||
private final InfoHash infoHash
|
||||
private final Name name, comment
|
||||
private final long timestamp
|
||||
private final Persona issuer
|
||||
final Name name, comment
|
||||
final long timestamp
|
||||
final Persona issuer
|
||||
private final byte[] sig
|
||||
|
||||
private volatile byte [] payload
|
||||
|
||||
private String base64;
|
||||
|
||||
Certificate(InputStream is) {
|
||||
version = (byte) (is.read() & 0xFF)
|
||||
if (version > Constants.FILE_CERT_VERSION)
|
||||
@ -131,6 +134,15 @@ class Certificate {
|
||||
os.write(payload)
|
||||
}
|
||||
|
||||
public String toBase64() {
|
||||
if (base64 == null) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()
|
||||
write(baos)
|
||||
base64 = Base64.encode(baos.toByteArray())
|
||||
}
|
||||
return base64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
version.hashCode() ^ infoHash.hashCode() ^ timestamp.hashCode() ^ name.hashCode() ^ issuer.hashCode() ^ Objects.hashCode(comment)
|
||||
|
@ -32,7 +32,8 @@ class CertificateClient {
|
||||
fetcherThread.execute({
|
||||
Endpoint endpoint = null
|
||||
try {
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.CONNECTING))
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.CONNECTING,
|
||||
user : e.host, infoHash : e.infoHash))
|
||||
endpoint = connector.connect(e.host.destination)
|
||||
|
||||
String infoHashString = Base64.encode(e.infoHash.getRoot())
|
||||
@ -62,7 +63,8 @@ class CertificateClient {
|
||||
int count = Integer.parseInt(headers['Count'])
|
||||
|
||||
// start pulling the certs
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FETCHING, count : count))
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FETCHING, count : count,
|
||||
user : e.host, infoHash : e.infoHash))
|
||||
|
||||
DataInputStream dis = new DataInputStream(is)
|
||||
for (int i = 0; i < count; i++) {
|
||||
@ -77,11 +79,14 @@ class CertificateClient {
|
||||
continue
|
||||
}
|
||||
if (cert.infoHash == e.infoHash)
|
||||
eventBus.publish(new CertificateFetchedEvent(certificate : cert))
|
||||
eventBus.publish(new CertificateFetchedEvent(certificate : cert, user : e.host, infoHash : e.infoHash))
|
||||
}
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.DONE, count : count,
|
||||
user : e.host, infoHash : e.infoHash))
|
||||
} catch (Exception bad) {
|
||||
log.log(Level.WARNING,"Fetching certificates failed", bad)
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FAILED))
|
||||
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FAILED,
|
||||
user : e.host, infoHash : e.infoHash))
|
||||
} finally {
|
||||
endpoint?.close()
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
package com.muwire.core.filecert
|
||||
|
||||
import com.muwire.core.Event
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.Persona
|
||||
|
||||
class CertificateFetchEvent extends Event {
|
||||
CertificateFetchStatus status
|
||||
int count
|
||||
Persona user
|
||||
InfoHash infoHash
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
package com.muwire.core.filecert
|
||||
|
||||
import com.muwire.core.Event
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.Persona
|
||||
|
||||
class CertificateFetchedEvent extends Event {
|
||||
Certificate certificate
|
||||
Persona user
|
||||
InfoHash infoHash
|
||||
}
|
||||
|
101
webui/src/main/java/com/muwire/webui/CertificateManager.java
Normal file
101
webui/src/main/java/com/muwire/webui/CertificateManager.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.muwire.webui;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.muwire.core.Core;
|
||||
import com.muwire.core.InfoHash;
|
||||
import com.muwire.core.Persona;
|
||||
import com.muwire.core.filecert.Certificate;
|
||||
import com.muwire.core.filecert.CertificateFetchEvent;
|
||||
import com.muwire.core.filecert.CertificateFetchStatus;
|
||||
import com.muwire.core.filecert.CertificateFetchedEvent;
|
||||
import com.muwire.core.filecert.UIFetchCertificatesEvent;
|
||||
import com.muwire.core.filecert.UIImportCertificateEvent;
|
||||
|
||||
public class CertificateManager {
|
||||
private final Core core;
|
||||
|
||||
|
||||
private final Map<Persona, Map<InfoHash,CertificateRequest>> requests = new ConcurrentHashMap<>();
|
||||
|
||||
public CertificateManager(Core core) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public void onCertificateFetchEvent(CertificateFetchEvent e) {
|
||||
Map<InfoHash, CertificateRequest> map = requests.get(e.getUser());
|
||||
if (map == null)
|
||||
return;
|
||||
CertificateRequest request = map.get(e.getInfoHash());
|
||||
if (request == null)
|
||||
return;
|
||||
request.status = e.getStatus();
|
||||
if (request.status == CertificateFetchStatus.FETCHING)
|
||||
request.totalCertificates = e.getCount();
|
||||
}
|
||||
|
||||
public void onCertificateFetchedEvent(CertificateFetchedEvent e) {
|
||||
Map<InfoHash, CertificateRequest> map = requests.get(e.getUser());
|
||||
if (map == null)
|
||||
return;
|
||||
CertificateRequest request = map.get(e.getInfoHash());
|
||||
if (request == null)
|
||||
return;
|
||||
request.certificates.add(e.getCertificate());
|
||||
}
|
||||
|
||||
void request(Persona user, InfoHash infoHash) {
|
||||
CertificateRequest request = new CertificateRequest(user, infoHash);
|
||||
Map<InfoHash, CertificateRequest> requestsFromUser = requests.get(user);
|
||||
if (requestsFromUser == null) {
|
||||
requestsFromUser = new ConcurrentHashMap<>();
|
||||
requests.put(user, requestsFromUser);
|
||||
}
|
||||
requestsFromUser.put(infoHash, request);
|
||||
|
||||
UIFetchCertificatesEvent event = new UIFetchCertificatesEvent();
|
||||
event.setHost(user);
|
||||
event.setInfoHash(infoHash);
|
||||
core.getEventBus().publish(event);
|
||||
}
|
||||
|
||||
CertificateRequest get(Persona user, InfoHash infoHash) {
|
||||
Map<InfoHash, CertificateRequest> map = requests.get(user);
|
||||
if (map == null)
|
||||
return null;
|
||||
return map.get(infoHash);
|
||||
}
|
||||
|
||||
void importCertificate(Certificate certificate) {
|
||||
UIImportCertificateEvent event = new UIImportCertificateEvent();
|
||||
event.setCertificate(certificate);
|
||||
core.getEventBus().publish(event);
|
||||
}
|
||||
|
||||
static class CertificateRequest {
|
||||
private final Persona user;
|
||||
private final InfoHash infoHash;
|
||||
private volatile CertificateFetchStatus status;
|
||||
private volatile int totalCertificates;
|
||||
private Set<Certificate> certificates;
|
||||
|
||||
CertificateRequest(Persona user, InfoHash infoHash) {
|
||||
this.user = user;
|
||||
this.infoHash = infoHash;
|
||||
}
|
||||
|
||||
CertificateFetchStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
int totalCertificates() {
|
||||
return totalCertificates;
|
||||
}
|
||||
|
||||
Set<Certificate> getCertificates() {
|
||||
return certificates;
|
||||
}
|
||||
}
|
||||
}
|
127
webui/src/main/java/com/muwire/webui/CertificateServlet.java
Normal file
127
webui/src/main/java/com/muwire/webui/CertificateServlet.java
Normal file
@ -0,0 +1,127 @@
|
||||
package com.muwire.webui;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.muwire.core.InfoHash;
|
||||
import com.muwire.core.Persona;
|
||||
import com.muwire.core.filecert.Certificate;
|
||||
import com.muwire.webui.CertificateManager.CertificateRequest;
|
||||
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
public class CertificateServlet extends HttpServlet {
|
||||
|
||||
private CertificateManager certificateManager;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String userB64 = req.getParameter("user");
|
||||
Persona user;
|
||||
try {
|
||||
user = new Persona(new ByteArrayInputStream(Base64.decode(userB64)));
|
||||
} catch (Exception bad) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
|
||||
String infoHashB64 = req.getParameter("infoHash");
|
||||
InfoHash infoHash;
|
||||
try {
|
||||
infoHash = new InfoHash(Base64.decode(infoHashB64));
|
||||
} catch (Exception bad) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
|
||||
CertificateRequest request = certificateManager.get(user, infoHash);
|
||||
if (request == null) {
|
||||
resp.sendError(404,"Not found");
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
|
||||
sb.append("<CertificateRequest>");
|
||||
sb.append("<Status>").append(request.getStatus().toString()).append("</Status>");
|
||||
sb.append("<Total>").append(request.totalCertificates()).append("</Total>");
|
||||
sb.append("<Certificates>");
|
||||
for (Certificate certificate : request.getCertificates()) {
|
||||
sb.append("<Certificate>");
|
||||
sb.append("<Issuer>").append(certificate.getIssuer().getHumanReadableName()).append("</Issuer>");
|
||||
sb.append("<Name>").append(Util.escapeHTMLinXML(certificate.getName().getName())).append("</Name>");
|
||||
if (certificate.getComment() != null)
|
||||
sb.append("<Comment>").append(Util.escapeHTMLinXML(certificate.getComment().getName())).append("</Comment>");
|
||||
sb.append("<Timestamp>").append(DataHelper.formatTime(certificate.getTimestamp())).append("</Timestamp>");
|
||||
sb.append("<Base64>").append(certificate.toBase64()).append("</Base64>");
|
||||
sb.append("</Certificate>");
|
||||
}
|
||||
sb.append("</Certificates>");
|
||||
sb.append("</CertificateRequest>");
|
||||
|
||||
resp.setContentType("text/xml");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.setDateHeader("Expires", 0);
|
||||
resp.setHeader("Pragma", "no-cache");
|
||||
resp.setHeader("Cache-Control", "no-store, max-age=0, no-cache, must-revalidate");
|
||||
byte[] out = sb.toString().getBytes("UTF-8");
|
||||
resp.setContentLength(out.length);
|
||||
resp.getOutputStream().write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String action = req.getParameter("action");
|
||||
if (action == null) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.equals("fetch")) {
|
||||
String userB64 = req.getParameter("user");
|
||||
Persona user;
|
||||
try {
|
||||
user = new Persona(new ByteArrayInputStream(Base64.decode(userB64)));
|
||||
} catch (Exception bad) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
|
||||
String infoHashB64 = req.getParameter("infoHash");
|
||||
InfoHash infoHash;
|
||||
try {
|
||||
infoHash = new InfoHash(Base64.decode(infoHashB64));
|
||||
} catch (Exception bad) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
|
||||
certificateManager.request(user, infoHash);
|
||||
} else if (action.equals("import")) {
|
||||
String certB64 = req.getParameter("base64");
|
||||
Certificate certificate;
|
||||
try {
|
||||
certificate = new Certificate(new ByteArrayInputStream(Base64.decode(certB64)));
|
||||
} catch (Exception bad) {
|
||||
resp.sendError(403, "Bad param");
|
||||
return;
|
||||
}
|
||||
certificateManager.importCertificate(certificate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
certificateManager = (CertificateManager) config.getServletContext().getAttribute("certificateManager");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -22,6 +22,8 @@ import com.muwire.core.UILoadedEvent;
|
||||
import com.muwire.core.connection.ConnectionEvent;
|
||||
import com.muwire.core.connection.DisconnectionEvent;
|
||||
import com.muwire.core.download.DownloadStartedEvent;
|
||||
import com.muwire.core.filecert.CertificateFetchEvent;
|
||||
import com.muwire.core.filecert.CertificateFetchedEvent;
|
||||
import com.muwire.core.files.AllFilesLoadedEvent;
|
||||
import com.muwire.core.files.FileDownloadedEvent;
|
||||
import com.muwire.core.files.FileHashedEvent;
|
||||
@ -148,12 +150,17 @@ public class MuWireClient {
|
||||
TrustManager trustManager = new TrustManager();
|
||||
core.getEventBus().register(TrustEvent.class, trustManager);
|
||||
|
||||
CertificateManager certificateManager = new CertificateManager(core);
|
||||
core.getEventBus().register(CertificateFetchedEvent.class, certificateManager);
|
||||
core.getEventBus().register(CertificateFetchEvent.class, certificateManager);
|
||||
|
||||
servletContext.setAttribute("searchManager", searchManager);
|
||||
servletContext.setAttribute("downloadManager", downloadManager);
|
||||
servletContext.setAttribute("connectionCounter", connectionCounter);
|
||||
servletContext.setAttribute("fileManager", fileManager);
|
||||
servletContext.setAttribute("browseManager", browseManager);
|
||||
servletContext.setAttribute("trustManager", trustManager);
|
||||
servletContext.setAttribute("certificateManager", certificateManager);
|
||||
|
||||
core.getEventBus().publish(new UILoadedEvent());
|
||||
}
|
||||
|
Reference in New Issue
Block a user