getTopLevelDomains() throws SQLException;
+ public abstract void handleMessage(ConnectionHandler connectionHandler, String message);
+ public abstract String getDNSServerInfoSite() throws SQLException;
+ public abstract String getInfoSite(String topLevelDomain) throws SQLException;
+ public abstract String getInterfaceSite() throws SQLException;
+
+ private NetworkServer server;
+ private ProtocolBridge protocolBridge;
+
+ public final void setProtocolBridge(ProtocolBridge protocolBridge) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+ this.protocolBridge = protocolBridge;
+
+ server = new NetworkServer.ServerBuilder()
+ .setEventManager(protocolBridge.getProtocolSettings().eventManager).setPacketHandler(protocolBridge.getProtocolSettings().packetHandler)
+ .setPort(protocolBridge.getProtocolSettings().port).build();
+ }
+
+ public final ProtocolBridge getProtocolBridge() {
+ return protocolBridge;
+ }
+
+ public final boolean startServer() throws Exception {
+ server.getEventManager().registerListener(ServerListener.class);
+ server.getEventManager().unregisterListener(ClientListener.class);
+
+ return server.start();
+ }
+
+ public final NetworkServer getServer() {
+ return server;
+ }
+
+ public final boolean stopServer() throws IOException {
+ server.getEventManager().unregisterListener(ServerListener.class);
+ return server.stop();
+ }
+
+ public final Domain ping(RequestDomain requestDomain) throws SQLException {
+ Domain domain = getDomain(requestDomain);
+ boolean reachable = false;
+
+ String destination = domain.parsedDestination();
+
+ if (!destination.startsWith("http://") && !destination.startsWith("https://")) destination = "http://" + destination;
+
+ HttpURLConnection connection = null;
+
+ try {
+ URL u = new URL(destination);
+
+ connection = (HttpURLConnection) u.openConnection();
+ connection.setRequestMethod("HEAD");
+
+ int code = connection.getResponseCode();
+
+ reachable = code == 200;
+ } catch (IOException exception) {
+ InetAddress address = null;
+ try {
+ InetAddress address1 = InetAddress.getByName(destination);
+ String ip = address1.getHostAddress();
+ address = InetAddress.getByName(ip);
+ reachable = address.isReachable(10000);
+ } catch (IOException exc) {
+ reachable = false;
+ exc.printStackTrace();
+ }
+
+ reachable = false;
+ exception.printStackTrace();
+ } finally {
+ if (connection != null) connection.disconnect();
+ }
+
+ return domain;
+ }
+
+ public final boolean domainExists(RequestDomain domain) throws SQLException {
+ return getDomain(domain) != null;
+ }
+
+ public final boolean domainExists(Domain domain) throws SQLException {
+ return domainExists(new RequestDomain(domain.name, domain.topLevelDomain, domain.getPath()));
+ }
+
+ public final Domain getDomain(RequestDomain domain) throws SQLException {
+ return getDomain(domain.name, domain.topLevelDomain, domain.getPath());
+ }
+
+ public final boolean topLevelDomainExists(String topLevelDomain) throws SQLException {
+ return topLevelDomain.equalsIgnoreCase("oac") || getTopLevelDomains().contains(topLevelDomain);
+ }
+
+ public final Domain getDomain(String name, String topLevelDomain, String path) throws SQLException {
+ if (!topLevelDomainExists(topLevelDomain)) return null;
+
+ if (name.equalsIgnoreCase("info") && topLevelDomain.equalsIgnoreCase("oac")) return new Domain(name, topLevelDomain, getDNSServerInfoSite(), path);
+ if (name.equalsIgnoreCase("interface") && topLevelDomain.equalsIgnoreCase("oac")) return new Domain(name, topLevelDomain, getInterfaceSite(), path);
+
+ if (name.equalsIgnoreCase("info")) return new Domain(name, topLevelDomain, getInfoSite(topLevelDomain), path);
+
+ for (Domain domain : getDomains()) if (domain.name.equals(name) && domain.topLevelDomain.equals(topLevelDomain)) return new Domain(domain.name, domain.topLevelDomain, domain.realDestination(), path);
+ return null;
+ }
+}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java b/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java
deleted file mode 100644
index 17a059f..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java
+++ /dev/null
@@ -1,340 +0,0 @@
-package org.openautonomousconnection.protocol.side.client;
-
-import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
-import dev.unlegitdqrk.unlegitlibrary.network.system.client.events.ClientDisconnectedEvent;
-import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
-import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.ProtocolBridge;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.packets.OACPacket;
-import org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSQueryPacket;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
-import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
-import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSResponseStatus;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.cert.CertificateException;
-import java.util.List;
-
-/**
- * Abstract class defining the client-side protocol operations and interactions with INS and web servers.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public abstract class ProtocolClient extends DefaultMethodsOverrider {
- /**
- * Handles everything with INS-Connection.
- */
- private final NetworkClient clientToINS;
-
- /**
- * Manages the folder structure for client certificates.
- */
- @Getter
- private final ClientCertificateFolderStructure folderStructure;
- /**
- * The reference to the ProtocolBridge Object
- */
- @Getter
- private final ProtocolBridge protocolBridge;
- /**
- * Stores the protocol version of the connected server.
- */
- private ProtocolVersion serverVersion = null;
-
- /**
- * Initializes the ProtocolClient, setting up certificate folders and the INS client connection.
- *
- * @throws CertificateException if there are issues with the certificates.
- * @throws IOException if there are I/O issues during initialization.
- */
- public ProtocolClient(ProtocolBridge protocolBridge) throws CertificateException, IOException {
- this.protocolBridge = protocolBridge;
-
- // Initialize and verify certificate folders and files
- folderStructure = new ClientCertificateFolderStructure();
-
- // Initialize connection to INS server
- clientToINS = new NetworkClient.ClientBuilder().setLogger(protocolBridge.getLogger()).setProxy(protocolBridge.getProxy()).
- setHost(protocolBridge.getProtocolSettings().host).setPort(protocolBridge.getProtocolSettings().port).
- setPacketHandler(protocolBridge.getProtocolSettings().packetHandler).setEventManager(protocolBridge.getProtocolSettings().eventManager).
- setRootCAFolder(folderStructure.publicCAFolder).setClientCertificatesFolder(folderStructure.publicClientFolder, folderStructure.privateClientFolder).
- build();
- }
-
- /**
- * Gets the INS connection client.
- *
- * @return the NetworkClient handling the INS connection.
- */
- public final NetworkClient getClientINSConnection() {
- return clientToINS;
- }
-
- /**
- * Checks if the required certificate files exist in the specified folder.
- *
- * @param folder the folder to check for certificate files.
- * @param prefix the prefix of the certificate files.
- * @param extension the extension of the certificate files.
- * @throws CertificateException if any required certificate file is missing or invalid.
- * @throws IOException if there are I/O issues during the check.
- */
- private final void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
- boolean found = false;
- // Check if folder exists
- if (folder == null) throw new FileNotFoundException("Folder does not exist");
-
- // List files in the folder
- File[] files = folder.listFiles();
-
- // Check if folder is empty
- if (files == null || files.length == 0)
- throw new FileNotFoundException("Folder " + folder.getAbsolutePath() + " is empty");
-
- // Validate each file in the folder
- for (File file : files) {
- if (!file.getName().startsWith(prefix))
- throw new CertificateException(file.getAbsolutePath() + " is not valid");
-
- // Check for specific files
- if (!found) found = file.getName().equalsIgnoreCase(prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- // If the specific file is not found, throw an exception
- if (!found) throw new CertificateException("Missing " + prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- /**
- * Gets the protocol version of the connected server.
- *
- * @return the ProtocolVersion of the server, or PV_1_0_0_CLASSIC if not set.
- */
- public final ProtocolVersion getServerVersion() {
- return serverVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : serverVersion;
- }
-
- /**
- * Sets the protocol version of the connected server.
- *
- * @param serverVersion the ProtocolVersion to set for the server.
- */
- public final void setServerVersion(ProtocolVersion serverVersion) {
- if (serverVersion == null) this.serverVersion = serverVersion;
- }
-
- /**
- * Handles INS disconnection events, resetting the server version and closing the web client connection if necessary.
- *
- * @param event the ClientDisconnectedEvent triggered on INS disconnection.
- */
- public final void onINSDisconnect(ClientDisconnectedEvent event) {
- // Reset server version on INS disconnect
- serverVersion = null;
- }
-
- /**
- * Checks if the connected server is a stable server.
- *
- * @return true if the server is stable, false otherwise.
- */
- public final boolean isStableServer() {
- // Check if the server version is stable
- return !isBetaServer() && !isClassicServer();
- }
-
- /**
- * Checks if the connected server or its compatible versions support stable protocol.
- *
- * @return true if stable protocol is supported, false otherwise.
- */
- public final boolean supportServerStable() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is stable
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
- if (yes) break;
- }
-
- // Check if the server version is stable
- return isStableServer() || yes;
- }
-
- /**
- * Checks if the connected server is a beta server.
- *
- * @return true if the server is beta, false otherwise.
- */
- public final boolean isBetaServer() {
- // Check if the server version is beta
- return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- }
-
- /**
- * Checks if the connected server or its compatible versions support beta protocol.
- *
- * @return true if beta protocol is supported, false otherwise.
- */
- public final boolean supportServerBeta() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is beta
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- if (yes) break;
- }
-
- // Check if the server version is beta
- return isBetaServer() || yes;
- }
-
- /**
- * Checks if the connected server is a classic server.
- *
- * @return true if the server is classic, false otherwise.
- */
- public final boolean isClassicServer() {
- // Check if the server version is classic
- return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- }
-
- /**
- * Checks if the connected server or its compatible versions support classic protocol.
- *
- * @return true if classic protocol is supported, false otherwise.
- */
- public final boolean supportServerClassic() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is classic
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- if (yes) break;
- }
-
- // Check if the server version is classic
- return isClassicServer() || yes;
- }
-
- /**
- * Checks if the connected server supports the protocol version of the given packet.
- *
- * @param packet the OACPacket to check against the server's supported protocol version.
- * @return true if the server supports the packet's protocol version, false otherwise.
- */
- public final boolean supportServerPacket(OACPacket packet) {
- // Check if the server supports the protocol version of the packet
- return supportServerVersion(packet.getProtocolVersion());
- }
-
- /**
- * Checks if the connected server or its compatible versions support the specified protocol version.
- *
- * @param targetVersion the ProtocolVersion to check for support.
- * @return true if the server or its compatible versions support the target version, false otherwise.
- */
- public final boolean supportServerVersion(ProtocolVersion targetVersion) {
- // Directly check if the server version matches or is in the list of compatible versions
- return getServerVersion() == targetVersion || getServerVersion().getCompatibleVersions().contains(targetVersion);
- }
-
- /**
- * Checks if the connected server or its compatible versions support the specified protocol.
- *
- * @param protocol the Protocol to check for support.
- * @return true if the server or its compatible versions support the protocol, false otherwise.
- */
- public final boolean supportServerProtocol(ProtocolVersion.Protocol protocol) {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version supports the protocol
- yes = compatibleVersion.getSupportedProtocols().contains(protocol);
- if (yes) break;
- }
-
- // Check if the server version supports the protocol
- return getServerVersion().getSupportedProtocols().contains(protocol) || yes;
- }
-
- /**
- * Sends an INS query to the INS server.
- *
- * The client requests a specific record type for a given TLN, name and optional subname.
- * After sending the packet, {@link #onQuerySent(String, String, String, INSRecordType)} is invoked.
- *
- * @param tln The TLN.
- * @param name The InfoName.
- * @param sub Optional subname or {@code null}.
- * @param type The requested record type.
- * @throws IOException If sending the packet fails.
- * @throws ClassNotFoundException If packet serialization fails.
- */
- public final void sendINSQuery(String tln, String name, String sub, INSRecordType type) throws IOException, ClassNotFoundException {
- if (!protocolBridge.isRunningAsClient()) return;
-
- getClientINSConnection().sendPacket(new INSQueryPacket(tln, name, sub, type, getClientINSConnection().getClientID()));
- onQuerySent(tln, name, sub, type);
- }
-
- /**
- * Called when the client receives an INS response from the server.
- *
- *
- * @param status The response status from the server.
- * @param records The list of records returned by the server.
- */
- public abstract void onResponse(INSResponseStatus status, List records);
-
- /**
- * Called after a query was sent to the INS server.
- *
- *
- * @param tln The TLN requested.
- * @param name The InfoName.
- * @param sub Optional subname.
- * @param type The requested record type.
- */
- public void onQuerySent(String tln, String name, String sub, INSRecordType type) {
- }
-
- /**
- * Manages the folder structure for client certificates.
- */
- public final class ClientCertificateFolderStructure {
- public final File certificatesFolder;
-
- public final File publicFolder;
- public final File privateFolder;
-
- public final File privateCAFolder;
- public final File privateClientFolder;
-
- public final File publicCAFolder;
- public final File publicClientFolder;
-
- public ClientCertificateFolderStructure() {
- certificatesFolder = new File("certificates");
-
- publicFolder = new File(certificatesFolder, "public");
- privateFolder = new File(certificatesFolder, "private");
-
- privateCAFolder = new File(privateFolder, "ca");
- privateClientFolder = new File(privateFolder, "client");
-
- publicCAFolder = new File(publicFolder, "ca");
- publicClientFolder = new File(publicFolder, "client");
-
- if (!certificatesFolder.exists()) certificatesFolder.mkdirs();
-
- if (!publicFolder.exists()) publicFolder.mkdirs();
- if (!privateFolder.exists()) privateFolder.mkdirs();
-
- if (!privateCAFolder.exists()) privateCAFolder.mkdirs();
- if (!privateClientFolder.exists()) privateClientFolder.mkdirs();
-
- if (!publicCAFolder.exists()) publicCAFolder.mkdirs();
- if (!publicClientFolder.exists()) publicClientFolder.mkdirs();
- }
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/client/events/ConnectedToProtocolINSServerEvent.java b/src/main/java/org/openautonomousconnection/protocol/side/client/events/ConnectedToProtocolINSServerEvent.java
deleted file mode 100644
index 901e985..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/client/events/ConnectedToProtocolINSServerEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.openautonomousconnection.protocol.side.client.events;
-
-import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.side.client.ProtocolClient;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Event triggered when a client successfully connects to a INS protocol server.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public final class ConnectedToProtocolINSServerEvent extends Event {
-
- /**
- * Reference to the ProtocolClient object.
- */
- @Getter
- private final ProtocolClient client;
-
- public ConnectedToProtocolINSServerEvent(ProtocolClient client) {
- this.client = client;
- }
-
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java
deleted file mode 100644
index 1f66462..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package org.openautonomousconnection.protocol.side.ins;
-
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.packets.OACPacket;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Represents a connected protocol client on the INS server side.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public final class ConnectedProtocolClient {
-
- /**
- * The connection handler associated with this protocol client.
- */
- @Getter
- private final ConnectionHandler connectionHandler;
-
- /**
- * The Protocol Server associated with this protocol client.
- */
- @Getter
- private final ProtocolINSServer protocolINSServer;
-
- /**
- * The protocol version of the connected client.
- */
- private ProtocolVersion clientVersion = null;
-
- public ConnectedProtocolClient(ConnectionHandler connectionHandler, ProtocolINSServer protocolINSServer) {
- this.connectionHandler = connectionHandler;
- this.protocolINSServer = protocolINSServer;
- }
-
- /**
- * Gets the protocol version of the connected client.
- * Defaults to PV_1_0_0_CLASSIC if not set.
- *
- * @return The protocol version of the client.
- */
- public ProtocolVersion getClientVersion() {
- return clientVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : clientVersion;
- }
-
- /**
- * Sets the protocol version of the connected client.
- *
- * @param clientVersion The protocol version to set.
- */
- public void setClientVersion(ProtocolVersion clientVersion) {
- if (clientVersion == null) this.clientVersion = clientVersion;
- }
-
- /**
- * Checks if the connected client is a stable client.
- *
- * @return True if the client is stable, false otherwise.
- */
- public boolean isStableClient() {
- // Check if the server version is stable
- return !isBetaClient() && !isClassicClient();
- }
-
- /**
- * Checks if the connected client supports stable protocol versions.
- *
- * @return True if the client supports stable versions, false otherwise.
- */
- public boolean supportClientStable() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is stable
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
- if (yes) break;
- }
-
- // Check if the client version is stable
- return isStableClient() || yes;
- }
-
- /**
- * Checks if the connected client is a beta client.
- *
- * @return True if the client is beta, false otherwise.
- */
- public boolean isBetaClient() {
- // Check if the server version is beta
- return getClientVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- }
-
- /**
- * Checks if the connected client supports beta protocol versions.
- *
- * @return True if the client supports beta versions, false otherwise.
- */
- public boolean supportClientBeta() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is beta
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- if (yes) break;
- }
-
- // Check if the client version is beta
- return isBetaClient() || yes;
- }
-
- /**
- * Checks if the connected client is a classic client.
- *
- * @return True if the client is classic, false otherwise.
- */
- public boolean isClassicClient() {
- // Check if the server version is classic
- return getClientVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- }
-
-
- /**
- * Checks if the connected client supports classic protocol versions.
- *
- * @return True if the client supports classic versions, false otherwise.
- */
- public boolean supportClientClassic() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is classic
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- if (yes) break;
- }
-
- // Check if the client version is classic
- return isClassicClient() || yes;
- }
-
- /**
- * Checks if the connected client supports the given packet's protocol version.
- *
- * @param packet The packet to check.
- * @return True if the client supports the packet's protocol version, false otherwise.
- */
- public boolean supportClientPacket(OACPacket packet) {
- return supportClientVersion(packet.getProtocolVersion());
- }
-
- /**
- * Checks if the connected client supports the given protocol version.
- *
- * @param targetVersion The protocol version to check.
- * @return True if the client supports the target version, false otherwise.
- */
- public boolean supportClientVersion(ProtocolVersion targetVersion) {
- // Check if the client version matches or is compatible with the target version
- return getClientVersion() == targetVersion || getClientVersion().getCompatibleVersions().contains(targetVersion);
- }
-
- /**
- * Checks if the connected client supports the given protocol.
- *
- * @param protocol The protocol to check.
- * @return True if the client supports the protocol, false otherwise.
- */
- public boolean supportClientProtocol(ProtocolVersion.Protocol protocol) {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version supports the protocol
- yes = compatibleVersion.getSupportedProtocols().contains(protocol);
- if (yes) break;
- }
-
- // Check if the client version supports the protocol
- return getClientVersion().getSupportedProtocols().contains(protocol) || yes;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
deleted file mode 100644
index 297d33f..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
+++ /dev/null
@@ -1,298 +0,0 @@
-package org.openautonomousconnection.protocol.side.ins;
-
-import dev.unlegitdqrk.unlegitlibrary.file.ConfigurationManager;
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
-import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
-import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.ProtocolBridge;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
-import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Abstract class representing a INS server in the protocol.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public abstract class ProtocolINSServer extends DefaultMethodsOverrider {
- /**
- * The network server instance.
- */
- @Getter
- private final NetworkServer networkServer;
-
- /**
- * The configuration manager for handling server configurations.
- */
- private final ConfigurationManager configurationManager;
- /**
- * The reference to the ProtocolBridge Object
- */
- @Getter
- private final ProtocolBridge protocolBridge;
- /**
- * List of connected protocol clients.
- */
- @Getter
- private List clients;
- /**
- * The folder structure for server certificates.
- */
- @Getter
- private ServerCertificateFolderStructure folderStructure;
-
- /**
- * Constructs a ProtocolINSServer with the specified configuration file.
- *
- * @param configFile The configuration file for the INS server.
- * @throws IOException If an I/O error occurs.
- * @throws CertificateException If a certificate error occurs.
- */
- public ProtocolINSServer(File configFile, ProtocolBridge protocolBridge) throws IOException, CertificateException {
- this.protocolBridge = protocolBridge;
- // Ensure the configuration file exists
- if (!configFile.exists()) configFile.createNewFile();
-
- // Load the configuration properties
- configurationManager = new ConfigurationManager(configFile);
- configurationManager.loadProperties();
-
- // Set default values for configuration properties if not already set
- if (!configurationManager.isSet("server.site.info")) {
- configurationManager.set("server.site.info", "INS-SERVER INFO SITE IP:PORT");
- configurationManager.saveProperties();
- }
-
- if (!configurationManager.isSet("server.site.frontend")) {
- configurationManager.set("server.site.frontend", "SERVER IP TO INS-FRONTEND:PORT");
- configurationManager.saveProperties();
- }
-
- // Initialize the folder structure
- folderStructure = new ServerCertificateFolderStructure();
-
- // Check for the existence of necessary certificate files
- checkFileExists(folderStructure.publicCAFolder, folderStructure.caPrefix, ".pem");
- checkFileExists(folderStructure.publicCAFolder, folderStructure.caPrefix, ".srl");
- checkFileExists(folderStructure.privateCAFolder, folderStructure.caPrefix, ".key");
-
- checkFileExists(folderStructure.publicServerFolder, folderStructure.certPrefix, ".crt");
- checkFileExists(folderStructure.privateServerFolder, folderStructure.certPrefix, ".key");
-
- // Define the certificate and key files based on the public IP address
- File certFile = new File(folderStructure.publicServerFolder, folderStructure.certPrefix + NetworkUtils.getPublicIPAddress() + ".crt");
- File keyFile = new File(folderStructure.privateServerFolder, folderStructure.certPrefix + NetworkUtils.getPublicIPAddress() + ".key");
-
- // Initialize the protocol bridge and clients list
- this.clients = new ArrayList<>();
-
- // Build the network server with the specified settings
- this.networkServer = new NetworkServer.ServerBuilder().
- setLogger(protocolBridge.getLogger()).
- setEventManager(protocolBridge.getProtocolSettings().eventManager).
- setPacketHandler(protocolBridge.getProtocolSettings().packetHandler).
- setPort(protocolBridge.getProtocolSettings().port).
- setRequireClientCertificate(false).setRootCAFolder(folderStructure.publicCAFolder).setServerCertificate(certFile, keyFile).
- build();
- }
-
-
- /**
- * Checks if the required certificate files exist in the specified folder.
- *
- * @param folder The folder to check for certificate files.
- * @param prefix The prefix of the certificate files.
- * @param extension The extension of the certificate files.
- * @throws CertificateException If a certificate error occurs.
- * @throws IOException If an I/O error occurs.
- */
- private final void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
- boolean found = false;
-
- // Check if the folder exists
- if (folder == null) throw new FileNotFoundException("Folder does not exist");
-
- // List all files in the folder
- File[] files = folder.listFiles();
-
- // Check if the folder is empty
- if (files == null || files.length == 0)
- throw new FileNotFoundException("Folder " + folder.getAbsolutePath() + " is empty");
-
- // Validate each file in the folder
- for (File file : files) {
- if (!file.getName().startsWith(prefix))
- throw new CertificateException(file.getAbsolutePath() + " is not valid");
-
- // Check if the file matches the expected naming convention
- if (!found) found = file.getName().equalsIgnoreCase(prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- // If the required file is not found, throw an exception
- if (!found) throw new CertificateException("Missing " + prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- /**
- * Retrieves a connected protocol client by its client ID.
- *
- * @param clientID The ID of the client to retrieve.
- * @return The ConnectedProtocolClient with the specified ID, or null if not found.
- */
- public final ConnectedProtocolClient getClientByID(int clientID) {
- for (ConnectedProtocolClient client : clients)
- if (client.getConnectionHandler().getClientID() == clientID) return client;
- return null;
- }
-
- /**
- * Gets the INS information site URL from the configuration.
- *
- * @return The INS information site URL.
- */
- public final String getINSInfoSite() {
- return configurationManager.getString("server.site.info");
- }
-
- /**
- * Resolves a request for an INS record based on TLN, name, subname and record type.
- *
- * The implementation should:
- *
- * - Locate the corresponding InfoName in storage
- * - Return all matching {@link INSRecord} entries
- * - Handle CNAME recursion, TTL rules, and filtering for the requested type
- *
- *
- * @param tln The top-level name.
- * @param name The InfoName.
- * @param sub The optional subname , may be {@code null}.
- * @param type The INS record type being requested.
- * @return A list of resolved INS records. May be empty if no record exists.
- */
- public abstract List resolve(String tln, String name, String sub, INSRecordType type);
-
- /**
- * Callback fired whenever the INS server receives a query packet.
- * This method is optional.
- *
- * @param tln The top-level name of the request.
- * @param name The InfoName being queried.
- * @param sub An optional subname, or {@code null}.
- * @param type The record type requested.
- */
- public void onQueryReceived(String tln, String name, String sub, INSRecordType type) {}
-
- /**
- * Callback fired after an INS response was successfully sent to the client.
- *
- * @param tln The requested TLN.
- * @param name The InfoName.
- * @param sub Optional subname or {@code null}.
- * @param type The requested record type.
- * @param results The records returned to the client.
- */
- public void onResponseSent(String tln, String name, String sub, INSRecordType type, List results) {}
-
- /**
- * Callback fired when an INS response could not be delivered to the client.
- *
- * @param tln The requested TLN.
- * @param name The InfoName.
- * @param sub Optional subname.
- * @param type The record type requested.
- * @param results The records that would have been sent.
- * @param exception The exception describing the failure.
- */
- public void onResponseSentFailed(String tln, String name, String sub, INSRecordType type, List results, Exception exception) {}
-
- /**
- * Resolves the information endpoint for a given Top-Level Name (TLN).
- *
- * This method is part of the INS server's internal resolution logic.
- * Each TLN
- * need to define a special "info site" which provides metadata, documentation,
- * or administrative information for that TLN.
- *
- *
The returned string must always be in the format:
- *
- * host:port
- *
- *
- * This method is used automatically by the INS protocol handler when a client
- * queries an InfoName of the form:
- *
- * info.<tln>
- *
- *
- * If no TLN-specific info endpoint exists or the TLN does not exist, the implementation can:
- *
- * - return
null to signal that no info site is registered
- *
- *
- * @param tln the top-level name for which the info site should be resolved.
- * Must not be null. Case-insensitive.
- *
- * @return a string in "host:port" format representing the TLN's info endpoint,
- * or null if the TLN has no registered info site.
- */
- public abstract String resolveTLNInfoSite(String tln);
-
- /**
- * Gets the INS registration site URL from the configuration.
- *
- * @return The INS registration site URL.
- */
- public final String getINSFrontendSite() {
- return configurationManager.getString("server.site.frontend");
- }
-
- /**
- * Class representing the folder structure for server certificates.
- */
- public final class ServerCertificateFolderStructure {
- public final File certificatesFolder;
-
- public final File publicFolder;
- public final File privateFolder;
-
- public final File privateCAFolder;
- public final File privateServerFolder;
-
- public final File publicCAFolder;
- public final File publicServerFolder;
- public final String caPrefix = "ca_ins_";
- public final String certPrefix = "cert_ins_";
-
- public ServerCertificateFolderStructure() {
- certificatesFolder = new File("certificates");
-
- publicFolder = new File(certificatesFolder, "public");
- privateFolder = new File(certificatesFolder, "private");
-
- privateCAFolder = new File(privateFolder, "ca");
- privateServerFolder = new File(privateFolder, "server");
-
- publicCAFolder = new File(publicFolder, "ca");
- publicServerFolder = new File(publicFolder, "server");
-
- if (!certificatesFolder.exists()) certificatesFolder.mkdirs();
-
- if (!publicFolder.exists()) publicFolder.mkdirs();
- if (!privateFolder.exists()) privateFolder.mkdirs();
-
- if (!privateCAFolder.exists()) privateCAFolder.mkdirs();
- if (!privateServerFolder.exists()) privateServerFolder.mkdirs();
-
- if (!publicCAFolder.exists()) publicCAFolder.mkdirs();
- if (!publicServerFolder.exists()) publicServerFolder.mkdirs();
- }
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/events/ConnectedProtocolClientEvent.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/events/ConnectedProtocolClientEvent.java
deleted file mode 100644
index 6891621..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/events/ConnectedProtocolClientEvent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.openautonomousconnection.protocol.side.ins.events;
-
-import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.side.ins.ConnectedProtocolClient;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Event triggered when a protocol client connects to the INS server.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public final class ConnectedProtocolClientEvent extends Event {
-
- @Getter
- private final ConnectedProtocolClient protocolClient;
-
- public ConnectedProtocolClientEvent(ConnectedProtocolClient protocolClient) {
- this.protocolClient = protocolClient;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java b/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java
deleted file mode 100644
index 48a36a9..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java
+++ /dev/null
@@ -1,734 +0,0 @@
-package org.openautonomousconnection.protocol.side.web;
-
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.packets.OACPacket;
-import org.openautonomousconnection.protocol.side.web.managers.AuthManager;
-import org.openautonomousconnection.protocol.side.web.managers.RuleManager;
-import org.openautonomousconnection.protocol.side.web.managers.SessionManager;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-import javax.net.ssl.SSLSocket;
-import java.io.*;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Represents a connected web client.
- * Manages the connection, handles HTTP requests, and serves files.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
-public final class ConnectedWebClient {
-
- /**
- * The connection handler associated with this web client.
- */
- @Getter
- private final ConnectionHandler pipelineConnection;
-
- /**
- * The SSL socket for the web client connection.
- */
- @Getter
- private SSLSocket webSocket;
-
- /**
- * The output stream for sending data to the client.
- */
- private ObjectOutputStream outputStream;
-
- /**
- * The input stream for receiving data from the client.
- */
- private ObjectInputStream inputStream;
-
- /**
- * The protocol version of the connected client.
- */
- private ProtocolVersion clientVersion = null;
- /**
- * Indicates if the client version has been loaded.
- */
- @Getter
- private boolean clientVersionLoaded = false;
- /**
- * The reference to the ProtocolWebServer Object
- */
- @Getter
- private ProtocolWebServer protocolWebServer;
-
- /**
- * Constructs a ConnectedWebClient with the given connection handler.
- *
- * @param pipelineConnection The connection handler for the web client.
- */
- public ConnectedWebClient(ConnectionHandler pipelineConnection) {
- this.pipelineConnection = pipelineConnection;
- }
-
- /**
- * Sends an HTTP redirect response to the client.
- *
- * @param out The output stream to send the response to.
- * @param location The URL to redirect to.
- * @param cookies Optional cookies to set in the response.
- * @throws IOException If an I/O error occurs.
- */
- private static void sendRedirect(OutputStream out, String location, Map cookies) throws IOException {
- // Send HTTP 302 Found response with Location header
- out.write(("OAC 302 Found\r\n").getBytes());
- out.write(("Location: " + location + "\r\n").getBytes());
-
- // Set cookies if provided
- if (cookies != null) {
- for (var entry : cookies.entrySet()) {
- out.write((entry.getKey() + ": " + entry.getValue() + "\r\n").getBytes());
- }
- }
-
- // End of headers
- out.write("\r\n".getBytes());
- out.flush();
- } /**
- * Thread for receiving data from the client.
- */
- private final Thread receiveThread = new Thread(this::receive);
-
- /**
- * Parses POST parameters from the input stream.
- *
- * @param in The input stream to read from.
- * @return A map of POST parameter names to values.
- * @throws IOException If an I/O error occurs.
- */
- private static Map parsePostParams(InputStream in) throws IOException {
- // Read the entire input stream into a string
- BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
- StringBuilder sb = new StringBuilder();
- while (reader.ready()) {
- sb.append((char) reader.read());
- }
-
- // Split the string into key-value pairs and decode them
- Map map = new HashMap<>();
- String[] pairs = sb.toString().split("&");
- for (String p : pairs) {
- // Split each pair into key and value
- String[] kv = p.split("=", 2);
- if (kv.length == 2)
- // Decode and store in the map
- map.put(URLDecoder.decode(kv[0], StandardCharsets.UTF_8), URLDecoder.decode(kv[1], StandardCharsets.UTF_8));
- }
- return map;
- }
-
- /**
- * Normalizes a file path to prevent directory traversal attacks.
- *
- * @param path The raw file path.
- * @return The normalized file path.
- */
- private static String normalizePath(String path) {
- // Replace backslashes with forward slashes and remove ".." segments
- path = path.replace("/", File.separator).replace("\\", "/");
- // Remove any ".." segments to prevent directory traversal
- while (path.contains("..")) path = path.replace("..", "");
-
- // Remove leading slashes
- if (path.startsWith("/")) path = path.substring(1);
-
- return path;
- }
-
- /**
- * Parses query parameters from a raw URL path.
- *
- * @param rawPath The raw URL path containing query parameters.
- * @return A map of query parameter names to values.
- */
- private static Map parseQueryParams(String rawPath) {
- // Extract query parameters from the URL path
- Map map = new HashMap<>();
- if (rawPath.contains("?")) {
- // Split the query string into key-value pairs
- String[] params = rawPath.substring(rawPath.indexOf("?") + 1).split("&");
- for (String p : params) {
- // Split each pair into key and value
- String[] kv = p.split("=");
- if (kv.length == 2) map.put(kv[0], kv[1]);
- }
- }
- return map;
- }
-
- /**
- * Checks if the request is a multipart/form-data request.
- *
- * @param headers The HTTP headers of the request.
- * @return True if the request is multipart/form-data, false otherwise.
- */
- private static boolean isMultipart(Map headers) {
- String contentType = headers.get("content-type");
- return contentType != null && contentType.startsWith("multipart/form-data");
- }
-
- /**
- * Handles a multipart/form-data request, saving uploaded files to the specified directory.
- *
- * @param in The input stream to read the request body from.
- * @param headers The HTTP headers of the request.
- * @param uploadDir The directory to save uploaded files to.
- * @throws IOException If an I/O error occurs.
- */
- private static void handleMultipart(InputStream in, Map headers, File uploadDir) throws IOException {
- // Ensure the upload directory exists
- if (!uploadDir.exists()) uploadDir.mkdirs();
-
- // Extract the boundary from the Content-Type header
- String contentType = headers.get("content-type");
- String boundary = "--" + contentType.split("boundary=")[1];
-
- // Read the entire request body into a buffer
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- byte[] lineBuffer = new byte[8192];
- int read;
- while ((read = in.read(lineBuffer)) != -1) {
- buffer.write(lineBuffer, 0, read);
- if (buffer.size() > 10 * 1024 * 1024) break; // 10 MB max
- }
-
- // Parse the multipart data
- String data = buffer.toString(StandardCharsets.UTF_8);
- String[] parts = data.split(boundary);
-
- // Process each part
- for (String part : parts) {
- if (part.contains("Content-Disposition")) {
- String name = null;
- String filename = null;
-
- // Extract headers from the part
- for (String headerLine : part.split("\r\n")) {
- if (headerLine.startsWith("Content-Disposition")) {
- if (headerLine.contains("filename=\"")) {
- int start = headerLine.indexOf("filename=\"") + 10;
- int end = headerLine.indexOf("\"", start);
- filename = headerLine.substring(start, end);
- }
- if (headerLine.contains("name=\"")) {
- int start = headerLine.indexOf("name=\"") + 6;
- int end = headerLine.indexOf("\"", start);
- name = headerLine.substring(start, end);
- }
- }
- }
-
- // Save the file if a filename is provided
- if (filename != null && !filename.isEmpty()) {
- int headerEnd = part.indexOf("\r\n\r\n");
- byte[] fileData = part.substring(headerEnd + 4).getBytes(StandardCharsets.UTF_8);
- File outFile = new File(uploadDir, filename);
- Files.write(outFile.toPath(), fileData);
- }
- }
- }
- }
-
- /**
- * Sends an response to the client.
- *
- * @param out
- * @param code
- * @param file
- * @param headers
- * @throws IOException
- */
- private static void sendResponse(OutputStream out, int code, File file, Map headers) throws IOException {
- byte[] body = Files.readAllBytes(file.toPath());
- sendResponse(out, code, body, "text/html", headers);
- }
-
- /**
- * Sends an response to the client.
- *
- * @param out The output stream to send the response to.
- * @param code The HTTP status code.
- * @param file The file to read the response body from.
- * @throws IOException If an I/O error occurs.
- */
- private static void sendResponse(OutputStream out, int code, File file) throws IOException {
- sendResponse(out, code, Files.readString(file.toPath()), "text/html");
- }
-
- /**
- * Sends an response to the client.
- *
- * @param out The output stream to send the response to.
- * @param code The HTTP status code.
- * @param body The response body as a string.
- * @param contentType The content type of the response.
- * @throws IOException If an I/O error occurs.
- */
- private static void sendResponse(OutputStream out, int code, String body, String contentType) throws IOException {
- sendResponse(out, code, body.getBytes(StandardCharsets.UTF_8), contentType, null);
- }
-
- /**
- * Sends an response to the client.
- *
- * @param out The output stream to send the response to.
- * @param code The HTTP status code.
- * @param file The file to read the response body from.
- * @param contentType The content type of the response.
- * @throws IOException If an I/O error occurs.
- */
- private static void sendResponse(OutputStream out, int code, File file, String contentType) throws IOException {
- byte[] bytes = Files.readAllBytes(file.toPath());
- sendResponse(out, code, bytes, contentType, null);
- }
-
- /**
- * Sends an response to the client.
- *
- * @param out The output stream to send the response to.
- * @param code The HTTP status code.
- * @param body The response body as a byte array.
- * @param contentType The content type of the response.
- * @param headers Additional headers to include in the response.
- * @throws IOException If an I/O error occurs.
- */
- private static void sendResponse(OutputStream out, int code, byte[] body, String contentType, Map headers) throws IOException {
- // Send response status line and headers
- out.write(("OAC " + code + " " + getStatusText(code) + "\r\n").getBytes());
- out.write(("Content-Type: " + contentType + "\r\n").getBytes());
- out.write(("Content-Length: " + body.length + "\r\n").getBytes());
-
- // Write additional headers if provided
- if (headers != null) headers.forEach((k, v) -> {
- try {
- out.write((k + ": " + v + "\r\n").getBytes());
- } catch (IOException ignored) {
- }
- });
-
- // End of headers
- out.write("\r\n".getBytes());
- out.write(body);
- out.flush();
- }
-
- /**
- * Returns the standard status text for a given status code.
- *
- * @param code The status code.
- * @return The corresponding status text.
- */
- private static String getStatusText(int code) {
- return switch (code) {
- case 200 -> "OK";
- case 301 -> "Moved Permanently";
- case 302 -> "Found";
- case 400 -> "Bad Request";
- case 401 -> "Unauthorized";
- case 403 -> "Forbidden";
- case 404 -> "Not Found";
- case 500 -> "Internal Server Error";
- default -> "Unknown";
- };
- }
-
- /**
- * Returns the content type based on the file extension.
- *
- * @param name The file name.
- * @return The corresponding content type.
- */
- private static String getContentType(String name) {
- return switch (name.substring(name.lastIndexOf('.') + 1).toLowerCase()) {
- case "html", "php" -> "text/html";
- case "js" -> "text/javascript";
- case "css" -> "text/css";
- case "json" -> "application/json";
- case "png" -> "image/png";
- case "jpg", "jpeg" -> "image/jpeg";
- case "mp4" -> "video/mp4";
- case "mp3" -> "audio/mpeg3";
- case "wav" -> "audio/wav";
- case "pdf" -> "application/pdf";
- default -> "text/plain";
- };
- }
-
- /**
- * Renders a PHP file by executing it with the PHP interpreter and captures cookies.
- *
- * @param file The PHP file to render.
- * @return A PHPResponse containing the output and cookies.
- * @throws IOException If an I/O error occurs.
- * @throws InterruptedException If the process is interrupted.
- */
- private static PHPResponse renderPHPWithCookies(File file) throws IOException, InterruptedException {
- // Execute the PHP file using the PHP interpreter
- ProcessBuilder pb = new ProcessBuilder("php", file.getAbsolutePath());
- pb.redirectErrorStream(true);
- Process p = pb.start();
-
- // Capture the output of the PHP process
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- InputStream processIn = p.getInputStream();
- byte[] buf = new byte[8192];
- int read;
- while ((read = processIn.read(buf)) != -1) {
- output.write(buf, 0, read);
- }
- p.waitFor();
-
- // Parse the output to separate headers and body, and extract cookies
- String fullOutput = output.toString(StandardCharsets.UTF_8);
- Map cookies = new HashMap<>();
-
- // Split headers and body
- String[] parts = fullOutput.split("\r\n\r\n", 2);
- String body;
- if (parts.length == 2) {
- // Get headers and body
- String headers = parts[0];
- body = parts[1];
-
- // Extract cookies from headers
- for (String headerLine : headers.split("\r\n")) {
- if (headerLine.toLowerCase().startsWith("set-cookie:")) {
- String cookie = headerLine.substring("set-cookie:".length()).trim();
- String[] kv = cookie.split(";", 2);
- String[] pair = kv[0].split("=", 2);
- if (pair.length == 2) cookies.put(pair[0], pair[1]);
- }
- }
- } else {
- // No headers, only body
- body = fullOutput;
- }
-
- return new PHPResponse(body, cookies);
- }
-
- /**
- * Sets the SSL socket for the web client and starts the receive thread.
- *
- * @param webSocket The SSL socket to set.
- */
- public void setWebSocket(SSLSocket webSocket) {
- if (webSocket != null) this.webSocket = webSocket;
- this.receiveThread.start();
- }
-
- /**
- * Checks if the web client is currently connected.
- *
- * @return True if connected, false otherwise.
- */
- public boolean isConnected() {
- return this.webSocket != null && this.webSocket.isConnected() && !this.webSocket.isClosed() && this.receiveThread.isAlive() && pipelineConnection.isConnected();
- }
-
- /**
- * Disconnects the web client, closing streams and the socket.
- *
- * @return True if disconnection was successful, false if already disconnected.
- */
- public synchronized boolean disconnect() {
- if (!this.isConnected()) {
- return false;
- } else {
- // Disconnect the underlying connection handler
- pipelineConnection.disconnect();
-
- // Interrupt the receive thread if it's still alive
- if (this.receiveThread.isAlive()) {
- this.receiveThread.interrupt();
- }
-
- try {
- // Close streams and the socket
- this.outputStream.close();
- this.inputStream.close();
- this.webSocket.close();
- } catch (IOException var2) {
- }
-
- // Nullify references
- this.webSocket = null;
- this.outputStream = null;
- this.inputStream = null;
-
- return true;
- }
- }
-
- /**
- * Gets the protocol version of the connected client.
- *
- * @return The protocol version of the client, defaults to PV_1_0_0_CLASSIC if not set.
- */
- public ProtocolVersion getClientVersion() {
- return clientVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : clientVersion;
- }
-
- /**
- * Sets the protocol version of the connected client.
- *
- * @param clientVersion The protocol version to set.
- */
- public void setClientVersion(ProtocolVersion clientVersion) {
- if (!clientVersionLoaded) clientVersionLoaded = true;
- if (clientVersion == null) this.clientVersion = clientVersion;
- }
-
- /**
- * Checks if the connected client is a stable client.
- *
- * @return True if the client is stable, false otherwise.
- */
- public boolean isStableClient() {
- // Check if the server version is stable
- return !isBetaClient() && !isClassicClient();
- }
-
- /**
- * Checks if the connected client supports stable protocol versions.
- *
- * @return True if the client supports stable versions, false otherwise.
- */
- public boolean supportClientStable() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is stable
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
- if (yes) break;
- }
-
- // Check if the client version is stable
- return isStableClient() || yes;
- }
-
- /**
- * Checks if the connected client is a beta client.
- *
- * @return True if the client is beta, false otherwise.
- */
- public boolean isBetaClient() {
- // Check if the server version is beta
- return getClientVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- }
-
- /**
- * Checks if the connected client supports beta protocol versions.
- *
- * @return True if the client supports beta versions, false otherwise.
- */
- public boolean supportClientBeta() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is beta
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
- if (yes) break;
- }
-
- // Check if the client version is beta
- return isBetaClient() || yes;
- }
-
- /**
- * Checks if the connected client is a classic client.
- *
- * @return True if the client is classic, false otherwise.
- */
- public boolean isClassicClient() {
- return getClientVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- }
-
- /**
- * Checks if the connected client supports classic protocol versions.
- *
- * @return True if the client supports classic versions, false otherwise.
- */
- public boolean supportClientClassic() {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version is classic
- yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
- if (yes) break;
- }
-
- // Check if the client version is classic
- return isClassicClient() || yes;
- }
-
- /**
- * Checks if the connected client supports the protocol version of the given packet.
- *
- * @param packet The packet to check support for.
- * @return True if the client supports the packet's protocol version, false otherwise.
- */
- public boolean supportClientPacket(OACPacket packet) {
- return supportClientVersion(packet.getProtocolVersion());
- }
-
- /**
- * Checks if the connected client supports the given protocol version.
- *
- * @param targetVersion The protocol version to check support for.
- * @return True if the client supports the target version, false otherwise.
- */
- public boolean supportClientVersion(ProtocolVersion targetVersion) {
- // Check if the client version matches the target version or is compatible
- return getClientVersion() == targetVersion || getClientVersion().getCompatibleVersions().contains(targetVersion);
- }
-
- /**
- * Checks if the connected client supports the given protocol.
- *
- * @param protocol The protocol to check support for.
- * @return True if the client supports the protocol, false otherwise.
- */
- public boolean supportClientProtocol(ProtocolVersion.Protocol protocol) {
- boolean yes = false;
- for (ProtocolVersion compatibleVersion : getClientVersion().getCompatibleVersions()) {
- // Check if compatible version supports the protocol
- yes = compatibleVersion.getSupportedProtocols().contains(protocol);
- if (yes) break;
- }
-
- // Check if the client version supports the protocol
- return getClientVersion().getSupportedProtocols().contains(protocol) || yes;
- }
-
- /**
- * Receives and processes requests from the client.
- * Handles authentication, file serving, and PHP rendering.
- */
- private void receive() {
- try {
- while (this.isConnected()) {
- Object received = this.inputStream.readObject();
-
- try (InputStream in = webSocket.getInputStream(); OutputStream out = webSocket.getOutputStream()) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
- String line;
- String path = "/main.html";
- Map headers = new HashMap<>();
- while ((line = reader.readLine()) != null && !line.isEmpty()) {
- if (line.toLowerCase().startsWith("get") || line.toLowerCase().startsWith("post")) {
- path = line.split(" ")[1];
- }
- if (line.contains(":")) {
- String[] parts = line.split(":", 2);
- headers.put(parts[0].trim().toLowerCase(), parts[1].trim());
- }
- }
-
- path = URLDecoder.decode(path, StandardCharsets.UTF_8);
- path = normalizePath(path);
-
- File file = new File(protocolWebServer.getProtocolBridge().getProtocolWebServer().getContentFolder(), path);
-
- String sessionId = null;
- if (headers.containsKey("cookie")) {
- for (String cookie : headers.get("cookie").split(";")) {
- cookie = cookie.trim();
- if (cookie.startsWith("SESSIONID=")) {
- sessionId = cookie.substring("SESSIONID=".length());
- }
- }
- }
-
- if (!file.exists() || !file.isFile()) {
- sendResponse(out, 404, new File(protocolWebServer.getProtocolBridge().getProtocolWebServer().getErrorsFolder(), "404.html"));
- return;
- }
-
- String clientIp = webSocket.getInetAddress().getHostAddress();
- String userAgent = headers.getOrDefault("user-agent", null);
-
- boolean loggedIn = sessionId != null && SessionManager.isValid(sessionId, clientIp, userAgent, protocolWebServer);
-
- if (path.equals("/403-login") && headers.getOrDefault("content-type", "").startsWith("application/x-www-form-urlencoded")) {
- Map postParams = parsePostParams(in);
- String login = postParams.get("login");
- String password = postParams.get("password");
-
- if (AuthManager.checkAuth(login, password)) {
- String newSessionId = SessionManager.create(login, clientIp, userAgent, protocolWebServer);
- Map cookies = Map.of("Set-Cookie", "SESSIONID=" + newSessionId + "; HttpOnly; Path=/");
- sendRedirect(out, "/main.html", cookies);
- return;
- } else {
- sendRedirect(out, "/403.php", null);
- return;
- }
- }
-
- if (isMultipart(headers)) {
- handleMultipart(in, headers, new File(protocolWebServer.getProtocolBridge().getProtocolWebServer().getContentFolder(), "uploads"));
- }
-
- if (RuleManager.requiresAuth(path) && !loggedIn) {
- PHPResponse phpResp = renderPHPWithCookies(new File(protocolWebServer.getProtocolBridge().getProtocolWebServer().getContentFolder(), "403.php"));
- sendResponse(out, 200, phpResp.body.getBytes(StandardCharsets.UTF_8), "text/html", phpResp.cookies);
- return;
- }
-
-
- if (RuleManager.isDenied(path) && !RuleManager.isAllowed(path)) {
- sendResponse(out, 403, new File(protocolWebServer.getProtocolBridge().getProtocolWebServer().getErrorsFolder(), "403.php"));
- return;
- }
-
- if (path.endsWith(".php")) {
- PHPResponse phpResp = renderPHPWithCookies(file);
- sendResponse(out, 200, phpResp.body.getBytes(StandardCharsets.UTF_8), "text/html", phpResp.cookies);
- } else {
- sendResponse(out, 200, Files.readAllBytes(file.toPath()), getContentType(path), null);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- disconnect();
- }
- }
- } catch (Exception var2) {
- this.disconnect();
- }
- }
-
- /**
- * Set protocol bridge
- *
- * @param protocolWebServer The ProtocolWebServer object
- */
- public void setProtocolWebServer(ProtocolWebServer protocolWebServer) {
- if (this.protocolWebServer == null) this.protocolWebServer = protocolWebServer;
- }
-
- /**
- * Represents the response from a PHP script, including body and cookies.
- */
- private static class PHPResponse {
- String body;
- Map cookies;
-
- public PHPResponse(String body, Map cookies) {
- this.body = body;
- this.cookies = cookies;
- }
- }
-
-
-
-
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java b/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java
deleted file mode 100644
index ff55a3f..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java
+++ /dev/null
@@ -1,377 +0,0 @@
-package org.openautonomousconnection.protocol.side.web;
-
-import dev.unlegitdqrk.unlegitlibrary.file.ConfigurationManager;
-import dev.unlegitdqrk.unlegitlibrary.file.FileUtils;
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
-import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
-import dev.unlegitdqrk.unlegitlibrary.string.RandomString;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.ProtocolBridge;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.side.web.managers.AuthManager;
-import org.openautonomousconnection.protocol.side.web.managers.RuleManager;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSocket;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Represents the web server for the protocol.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
-public final class ProtocolWebServer {
- /**
- * Folder for web content.
- */
- @Getter
- private final File contentFolder;
-
- /**
- * Folder for error pages.
- */
- @Getter
- private final File errorsFolder;
-
- /**
- * Structure for server.
- */
- @Getter
- private final ServerCertificateFolderStructure folderStructure;
-
- /**
- * Configuration manager for server settings.
- */
- private final ConfigurationManager configurationManager;
-
- /**
- * Certificate files for SSL.
- */
- private final File certFile;
- /**
- * Certificate files for SSL.
- */
- private final File keyFile;
- /**
- * The configuration file for the web server.
- */
- private final File configFile;
- /**
- * The reference to the ProtocolBridge Object
- */
- @Getter
- private final ProtocolBridge protocolBridge;
- /**
- * The network server handling pipeline connections.
- */
- @Getter
- private NetworkServer pipelineServer;
- /**
- * The SSL server socket for web connections.
- */
- @Getter
- private SSLServerSocket webServer;
- /**
- * List of connected web clients.
- */
- @Getter
- private List clients;
- /**
- * A unique secret for session management.
- */
- @Getter
- private String uniqueSessionString;
-
- /**
- * Initializes the web server with the given configuration, authentication, and rules files.
- *
- * @param configFile The configuration file.
- * @param authFile The authentication file.
- * @param rulesFile The rules file.
- * @throws Exception If an error occurs during initialization.
- */
- public ProtocolWebServer(File configFile, File authFile, File rulesFile, ProtocolBridge protocolBridge) throws Exception {
- this.protocolBridge = protocolBridge;
-
- // Initialize the list of connected clients
- this.clients = new ArrayList<>();
-
- // Store the configuration file
- this.configFile = configFile;
-
- // Set up folder structure for certificates
- folderStructure = new ServerCertificateFolderStructure();
-
- // Check for necessary certificate files
- checkFileExists(folderStructure.publicServerFolder, folderStructure.certPrefix, ".crt");
- checkFileExists(folderStructure.privateServerFolder, folderStructure.certPrefix, ".key");
-
- // Load configuration settings
- this.configurationManager = getConfigurationManager(configFile);
-
- // Set up content and error folders
- contentFolder = new File("content");
- errorsFolder = new File("errors");
-
- // Create folders if they don't exist
- if (!contentFolder.exists()) contentFolder.mkdir();
- if (!errorsFolder.exists()) errorsFolder.mkdir();
-
- // Set up certificate files based on public IP address
- this.certFile = new File(folderStructure.publicServerFolder, folderStructure.certPrefix + NetworkUtils.getPublicIPAddress() + ".crt");
- this.keyFile = new File(folderStructure.privateServerFolder, folderStructure.certPrefix + NetworkUtils.getPublicIPAddress() + ".key");
-
- // Create auth and rules files with default content if they don't exist
- if (!authFile.exists()) {
- authFile.createNewFile();
- FileUtils.writeFile(authFile, """
- admin:5e884898da28047151d0e56f8dc6292773603d0d6aabbddab8f91d8e5f99f6c7
- user:e99a18c428cb38d5f260853678922e03abd8335f
- """);
- }
-
- // Create default rules file if it doesn't exist
- if (!rulesFile.exists()) {
- rulesFile.createNewFile();
- FileUtils.writeFile(rulesFile, """
- {
- "allow": [
- "index.html",
- "css/*",
- "private/info.php"
- ],
- "deny": [
- "private/*"
- ],
- "auth": [
- "private/*",
- "admin/*"
- ]
- }
- """);
- }
-
- // Load authentication and rules
- uniqueSessionString = AuthManager.sha256(new RandomString(new Random(System.currentTimeMillis()).nextInt(10, 20)).nextString());
-
- AuthManager.loadAuthFile(authFile);
- RuleManager.loadRules(rulesFile);
-
- // Initialize the pipeline server
- pipelineServer = new NetworkServer.ServerBuilder().
- setPort(configurationManager.getInt("port.pipeline")).setTimeout(0).
- setPacketHandler(protocolBridge.getProtocolSettings().packetHandler).setEventManager(protocolBridge.getProtocolSettings().eventManager).
- setLogger(protocolBridge.getLogger()).
- setServerCertificate(certFile, keyFile).setRootCAFolder(folderStructure.publicCAFolder).
- build();
- }
-
- /**
- * Retrieves a connected web client by its client ID.
- *
- * @param clientID The client ID to search for.
- * @return The connected web client with the specified ID, or null if not found.
- */
- public ConnectedWebClient getClientByID(int clientID) {
- for (ConnectedWebClient client : clients)
- if (client.getPipelineConnection().getClientID() == clientID) return client;
- return null;
- }
-
- /**
- * Starts the web server to accept and handle client connections.
- *
- * @throws Exception If an error occurs while starting the server.
- */
- public void startWebServer() throws Exception {
- // Start the pipeline server
- pipelineServer.start();
-
- // Create the SSL server socket for web connections
- webServer = (SSLServerSocket) NetworkServer.ServerBuilder.
- createSSLServerSocketFactory(folderStructure.publicCAFolder, certFile, keyFile).
- createServerSocket(configurationManager.getInt("port"));
- webServer.setSoTimeout(0);
- webServer.setEnabledProtocols(pipelineServer.getServerSocket().getEnabledProtocols());
-
- // Stop WebServer if pipelineServer dies
- new Thread(() -> {
- while (true) {
- // Check if the pipeline server is still running
- if (pipelineServer == null || !pipelineServer.getServerSocket().isBound()) {
- try {
- // Stop the web server
- onPipelineStop();
- } catch (IOException e) {
- pipelineServer.getLogger().exception("Failed to stop WebServer", e);
- }
-
- Thread.currentThread().interrupt();
- break;
- }
-
- try {
- // Sleep for a while before checking again
- Thread.sleep(1000);
- } catch (InterruptedException ignored) {
- }
- }
- }).start();
-
- // Handle every client
- new Thread(() -> {
- while (true) {
- try {
- // Accept incoming client connections
- SSLSocket client = (SSLSocket) webServer.accept();
-
- for (ConnectedWebClient connectedWebClient : clients) {
- if (connectedWebClient.getPipelineConnection().getClientID() != -1 && connectedWebClient.isClientVersionLoaded()) {
- // Assign socket to an existing connected client
- connectedWebClient.setWebSocket(client);
- connectedWebClient.setProtocolWebServer(this);
- }
- }
- } catch (IOException e) {
- pipelineServer.getLogger().exception("Failed to accept WebClient", e);
- }
- }
- }).start();
- }
-
- /**
- * Handles the shutdown of the web server when the pipeline server stops.
- *
- * @throws IOException If an I/O error occurs while closing the web server.
- */
- private void onPipelineStop() throws IOException {
- webServer.close();
- }
-
- /**
- * Checks if the required certificate files exist in the specified folder.
- *
- * @param folder The folder to check for certificate files.
- * @param prefix The prefix of the certificate files.
- * @param extension The extension of the certificate files.
- * @throws CertificateException If a required certificate file is missing or invalid.
- * @throws IOException If an I/O error occurs while checking the files.
- */
- private void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
- boolean found = false;
-
- // Ensure the folder exists
- if (folder == null) throw new FileNotFoundException("Folder does not exist");
-
- // List all files in the folder
- File[] files = folder.listFiles();
- if (files == null || files.length == 0)
- throw new FileNotFoundException("Folder " + folder.getAbsolutePath() + " is empty");
-
- // Check for the required certificate file
- for (File file : files) {
- if (!file.getName().startsWith(prefix))
- throw new CertificateException(file.getAbsolutePath() + " is not valid");
-
- // Check for file matching the public IP address
- if (!found) found = file.getName().equalsIgnoreCase(prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- // Throw exception if the required file is not found
- if (!found) throw new CertificateException("Missing " + prefix + NetworkUtils.getPublicIPAddress() + extension);
- }
-
- /**
- * Retrieves the configuration manager for the web server.
- *
- * @return The configuration manager.
- * @throws IOException If an I/O error occurs while loading or saving the configuration.
- */
- public ConfigurationManager getConfigurationManager() throws IOException {
- return getConfigurationManager(configFile);
- }
-
- /**
- * Loads and initializes the configuration manager with default settings if necessary.
- *
- * @param configFile The configuration file to load.
- * @return The initialized configuration manager.
- * @throws IOException If an I/O error occurs while loading or saving the configuration.
- */
- private ConfigurationManager getConfigurationManager(File configFile) throws IOException {
- if (!configFile.exists()) configFile.createNewFile();
-
- ConfigurationManager configurationManager = new ConfigurationManager(configFile);
- configurationManager.loadProperties();
-
- if (!configurationManager.isSet("port.webserver")) {
- configurationManager.set("port.webserver", 9824);
- configurationManager.saveProperties();
- }
-
- if (!configurationManager.isSet("port.pipeline")) {
- configurationManager.set("port.pipeline", 9389);
- configurationManager.saveProperties();
- }
-
- if (!configurationManager.isSet("filemaxuploadmb")) {
- configurationManager.set("filemaxuploadmb", 1000);
- configurationManager.saveProperties();
- }
-
- if (!configurationManager.isSet("sessionexpireminutes")) {
- configurationManager.set("sessionexpireminutes", 60);
- configurationManager.saveProperties();
- }
-
- return configurationManager;
- }
-
- /**
- * Represents the folder structure for server certificates.
- */
- public final class ServerCertificateFolderStructure {
- public final File certificatesFolder;
-
- public final File publicFolder;
- public final File privateFolder;
-
- public final File privateCAFolder;
- public final File privateServerFolder;
-
- public final File publicCAFolder;
- public final File publicServerFolder;
- public final String caPrefix = "ca_server_";
- public final String certPrefix = "cert_server_";
-
- public ServerCertificateFolderStructure() {
- certificatesFolder = new File("certificates");
-
- publicFolder = new File(certificatesFolder, "public");
- privateFolder = new File(certificatesFolder, "private");
-
- privateCAFolder = new File(privateFolder, "ca");
- privateServerFolder = new File(privateFolder, "server");
-
- publicCAFolder = new File(publicFolder, "ca");
- publicServerFolder = new File(publicFolder, "server");
-
- if (!certificatesFolder.exists()) certificatesFolder.mkdirs();
-
- if (!publicFolder.exists()) publicFolder.mkdirs();
- if (!privateFolder.exists()) privateFolder.mkdirs();
-
- if (!privateCAFolder.exists()) privateCAFolder.mkdirs();
- if (!privateServerFolder.exists()) privateServerFolder.mkdirs();
-
- if (!publicCAFolder.exists()) publicCAFolder.mkdirs();
- if (!publicServerFolder.exists()) publicServerFolder.mkdirs();
- }
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/events/ConnectedWebClientEvent.java b/src/main/java/org/openautonomousconnection/protocol/side/web/events/ConnectedWebClientEvent.java
deleted file mode 100644
index 6a2cfd4..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/events/ConnectedWebClientEvent.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.openautonomousconnection.protocol.side.web.events;
-
-import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.side.web.ConnectedWebClient;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Event triggered when a web client connects to the web server.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
-public final class ConnectedWebClientEvent extends Event {
-
- /**
- * The connected web client.
- */
- @Getter
- private final ConnectedWebClient webClient;
-
- public ConnectedWebClientEvent(ConnectedWebClient webClient) {
- this.webClient = webClient;
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/managers/AuthManager.java b/src/main/java/org/openautonomousconnection/protocol/side/web/managers/AuthManager.java
deleted file mode 100644
index b0a21d2..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/managers/AuthManager.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.openautonomousconnection.protocol.side.web.managers;
-
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.security.MessageDigest;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Manages authentication for web clients.
- * Loads user credentials from a file and verifies login attempts.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
-public final class AuthManager {
-
- /**
- * Map of usernames to their SHA-256 hashed passwords
- */
- private static final Map users = new HashMap<>();
-
- /**
- * Loads the authentication file and populates the users map.
- * The file should contain lines in the format: username:hashed_password
- * Lines starting with '#' are treated as comments and ignored.
- *
- * @param authFile The authentication file to load.
- * @throws IOException If an I/O error occurs reading from the file.
- */
- public static void loadAuthFile(File authFile) throws IOException {
- // Create the file if it doesn't exist
- if (!authFile.exists()) authFile.createNewFile();
- for (String line : Files.readAllLines(authFile.toPath(), StandardCharsets.UTF_8)) {
- // Trim whitespace and ignore comments/empty lines
- line = line.trim();
- if (line.isEmpty() || line.startsWith("#")) continue;
-
- // Split the line into username and hashed password
- String[] parts = line.split(":", 2);
- if (parts.length == 2) {
- users.put(parts[0], parts[1]);
- }
- }
- }
-
- /**
- * Checks if the provided login and password are valid.
- *
- * @param login The username to check.
- * @param password The password to verify.
- * @return True if the credentials are valid, false otherwise.
- */
- public static boolean checkAuth(String login, String password) {
- // Retrieve the stored hashed password for the given username
- String storedHash = users.get(login);
- if (storedHash == null) return false;
-
- // Hash the provided password and compare it to the stored hash
- String hash = sha256(password);
- return storedHash.equalsIgnoreCase(hash);
- }
-
- /**
- * Computes the SHA-256 hash of the given input string.
- *
- * @param input The input string to hash.
- * @return The hexadecimal representation of the SHA-256 hash.
- */
- public static String sha256(String input) {
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
-
- // Convert the byte array to a hexadecimal string
- StringBuilder sb = new StringBuilder();
- for (byte b : digest) sb.append(String.format("%02x", b));
- return sb.toString();
- } catch (Exception e) {
- return "";
- }
- }
-}
-
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/managers/RuleManager.java b/src/main/java/org/openautonomousconnection/protocol/side/web/managers/RuleManager.java
deleted file mode 100644
index ae7a858..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/managers/RuleManager.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.openautonomousconnection.protocol.side.web.managers;
-
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Manages access rules for web resources.
- * Loads allow, deny, and auth rules from a JSON file and provides methods to check access.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
-public final class RuleManager {
- /**
- * Lists of path patterns for allow, deny, and auth rules
- */
- private static List allow;
-
- /**
- * Lists of path patterns for allow, deny, and auth rules
- */
- private static List deny;
-
- /**
- * Lists of path patterns for allow, deny, and auth rules
- */
- private static List auth;
-
- /**
- * Loads rules from a JSON file.
- * The JSON should have the structure:
- * {
- * "allow": ["pattern1", "pattern2", ...],
- * "deny": ["pattern1", "pattern2", ...],
- * "auth": ["pattern1", "pattern2", ...]
- * }
- *
- * @param rulesFile The JSON file containing the rules.
- * @throws Exception If an error occurs reading the file or parsing JSON.
- */
- public static void loadRules(File rulesFile) throws Exception {
- // Load and parse the JSON file
- String json = new String(Files.readAllBytes(rulesFile.toPath()));
- Map> map = new Gson().fromJson(json, new TypeToken