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.Signature
|
||||||
import net.i2p.data.SigningPrivateKey
|
import net.i2p.data.SigningPrivateKey
|
||||||
import net.i2p.data.SigningPublicKey
|
import net.i2p.data.SigningPublicKey
|
||||||
|
import net.i2p.data.Base64
|
||||||
|
|
||||||
class Certificate {
|
class Certificate {
|
||||||
private final byte version
|
private final byte version
|
||||||
private final InfoHash infoHash
|
private final InfoHash infoHash
|
||||||
private final Name name, comment
|
final Name name, comment
|
||||||
private final long timestamp
|
final long timestamp
|
||||||
private final Persona issuer
|
final Persona issuer
|
||||||
private final byte[] sig
|
private final byte[] sig
|
||||||
|
|
||||||
private volatile byte [] payload
|
private volatile byte [] payload
|
||||||
|
|
||||||
|
private String base64;
|
||||||
|
|
||||||
Certificate(InputStream is) {
|
Certificate(InputStream is) {
|
||||||
version = (byte) (is.read() & 0xFF)
|
version = (byte) (is.read() & 0xFF)
|
||||||
if (version > Constants.FILE_CERT_VERSION)
|
if (version > Constants.FILE_CERT_VERSION)
|
||||||
@ -131,6 +134,15 @@ class Certificate {
|
|||||||
os.write(payload)
|
os.write(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toBase64() {
|
||||||
|
if (base64 == null) {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream()
|
||||||
|
write(baos)
|
||||||
|
base64 = Base64.encode(baos.toByteArray())
|
||||||
|
}
|
||||||
|
return base64;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
version.hashCode() ^ infoHash.hashCode() ^ timestamp.hashCode() ^ name.hashCode() ^ issuer.hashCode() ^ Objects.hashCode(comment)
|
version.hashCode() ^ infoHash.hashCode() ^ timestamp.hashCode() ^ name.hashCode() ^ issuer.hashCode() ^ Objects.hashCode(comment)
|
||||||
|
@ -32,7 +32,8 @@ class CertificateClient {
|
|||||||
fetcherThread.execute({
|
fetcherThread.execute({
|
||||||
Endpoint endpoint = null
|
Endpoint endpoint = null
|
||||||
try {
|
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)
|
endpoint = connector.connect(e.host.destination)
|
||||||
|
|
||||||
String infoHashString = Base64.encode(e.infoHash.getRoot())
|
String infoHashString = Base64.encode(e.infoHash.getRoot())
|
||||||
@ -62,7 +63,8 @@ class CertificateClient {
|
|||||||
int count = Integer.parseInt(headers['Count'])
|
int count = Integer.parseInt(headers['Count'])
|
||||||
|
|
||||||
// start pulling the certs
|
// 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)
|
DataInputStream dis = new DataInputStream(is)
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@ -77,11 +79,14 @@ class CertificateClient {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (cert.infoHash == e.infoHash)
|
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) {
|
} catch (Exception bad) {
|
||||||
log.log(Level.WARNING,"Fetching certificates failed", 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 {
|
} finally {
|
||||||
endpoint?.close()
|
endpoint?.close()
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package com.muwire.core.filecert
|
package com.muwire.core.filecert
|
||||||
|
|
||||||
import com.muwire.core.Event
|
import com.muwire.core.Event
|
||||||
|
import com.muwire.core.InfoHash
|
||||||
|
import com.muwire.core.Persona
|
||||||
|
|
||||||
class CertificateFetchEvent extends Event {
|
class CertificateFetchEvent extends Event {
|
||||||
CertificateFetchStatus status
|
CertificateFetchStatus status
|
||||||
int count
|
int count
|
||||||
|
Persona user
|
||||||
|
InfoHash infoHash
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package com.muwire.core.filecert
|
package com.muwire.core.filecert
|
||||||
|
|
||||||
import com.muwire.core.Event
|
import com.muwire.core.Event
|
||||||
|
import com.muwire.core.InfoHash
|
||||||
|
import com.muwire.core.Persona
|
||||||
|
|
||||||
class CertificateFetchedEvent extends Event {
|
class CertificateFetchedEvent extends Event {
|
||||||
Certificate certificate
|
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.ConnectionEvent;
|
||||||
import com.muwire.core.connection.DisconnectionEvent;
|
import com.muwire.core.connection.DisconnectionEvent;
|
||||||
import com.muwire.core.download.DownloadStartedEvent;
|
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.AllFilesLoadedEvent;
|
||||||
import com.muwire.core.files.FileDownloadedEvent;
|
import com.muwire.core.files.FileDownloadedEvent;
|
||||||
import com.muwire.core.files.FileHashedEvent;
|
import com.muwire.core.files.FileHashedEvent;
|
||||||
@ -148,12 +150,17 @@ public class MuWireClient {
|
|||||||
TrustManager trustManager = new TrustManager();
|
TrustManager trustManager = new TrustManager();
|
||||||
core.getEventBus().register(TrustEvent.class, 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("searchManager", searchManager);
|
||||||
servletContext.setAttribute("downloadManager", downloadManager);
|
servletContext.setAttribute("downloadManager", downloadManager);
|
||||||
servletContext.setAttribute("connectionCounter", connectionCounter);
|
servletContext.setAttribute("connectionCounter", connectionCounter);
|
||||||
servletContext.setAttribute("fileManager", fileManager);
|
servletContext.setAttribute("fileManager", fileManager);
|
||||||
servletContext.setAttribute("browseManager", browseManager);
|
servletContext.setAttribute("browseManager", browseManager);
|
||||||
servletContext.setAttribute("trustManager", trustManager);
|
servletContext.setAttribute("trustManager", trustManager);
|
||||||
|
servletContext.setAttribute("certificateManager", certificateManager);
|
||||||
|
|
||||||
core.getEventBus().publish(new UILoadedEvent());
|
core.getEventBus().publish(new UILoadedEvent());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user