package org.intellimate.izou.security;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.intellimate.izou.main.Main;
import org.intellimate.izou.support.SystemMail;
import org.intellimate.izou.util.IzouModule;
import java.io.File;
/**
* The SecurityBreachHandler takes action when a security exception is thrown in the security manager to deal with the
* attempted security breach.
*/
final class SecurityBreachHandler extends IzouModule {
private final Logger logger = LogManager.getLogger(this.getClass());
private final String toAddress;
private final SystemMail systemMail;
private static boolean exists = false;
/**
* Creates a SecurityBreachHandler. There can only be one single SecurityBreachHandler, so calling this method twice
* will cause an illegal access exception.
*
* @param main the main instance of izou
* @param systemMail the system mail object in order to send e-mails to owner in case of emergency
* @param toAddress the email address to send error reports to
* @return an SecurityBreachHandler
* @throws IllegalAccessException thrown if this method is called more than once
*/
static SecurityBreachHandler createBreachHandler(Main main, SystemMail systemMail, String toAddress)
throws IllegalAccessException {
if (!exists) {
SecurityBreachHandler breachHandler = new SecurityBreachHandler(main, systemMail, toAddress);
exists = true;
return breachHandler;
}
throw new IllegalAccessException("Cannot create more than one instance of SecurityBreachHandler");
}
/**
Creates a new SecurityBreachHandler instance if and only if none has been created yet
*
* @param main the main instance of izou
* @param systemMail the system mail object in order to send e-mails to owner in case of emergency
* @param toAddress the email address to send error reports to
* @throws IllegalAccessException thrown if this method is called more than once
*/
private SecurityBreachHandler(Main main, SystemMail systemMail, String toAddress) throws IllegalAccessException {
super(main);
if (exists) {
throw new IllegalAccessException("Cannot create more than one instance of SecurityBreachHandler");
}
this.systemMail = systemMail;
this.toAddress = toAddress;
}
/**
* Handles the potential security breach (sends out an email and does whatever else is necessary)
*
* @param e The exception that will be thrown
* @param classesStack the current class stack
*/
void handleBreach(Exception e, Class[] classesStack) {
String subject = "Izou Security Exception: " + e.getMessage();
sendErrorReport(subject, e, classesStack);
}
private void sendErrorReport(String subject, Exception e, Class[] classesStack) {
String content = generateContent(e, classesStack);
String logName = "org.intellimate.izou.log";
String logAttachment = getMain().getFileSystemManager().getLogsLocation() + File.separator + logName;
systemMail.sendMail(toAddress, subject, content, logName, logAttachment);
}
private String generateContent(Exception excep, Class[] classesStack) {
String intro = "An attempted security breach was discovered in Izou: \n\n\n";
String exception = "EXCEPTION: \n\n";
exception += excep.getMessage() + "\n";
StackTraceElement[] stackTraceElements = excep.getStackTrace();
for (StackTraceElement element : stackTraceElements) {
exception += element.toString() + "\n";
}
exception += "\n\n\n";
String classesStackString = "";
if (classesStack != null) {
classesStackString = "CLASS STACK:\n\n";
for (int i = 0; i < classesStack.length; i++) {
Class clazz = classesStack[i];
classesStackString += "Class " + i + ": \n";
classesStackString += clazz.toString() + "\n";
classesStackString += "Class Loader " + i + ": \n";
ClassLoader classLoader = clazz.getClassLoader();
if (classLoader == null) {
classesStackString += "null\n";
} else {
classesStackString += clazz.getClassLoader().toString() + "\n";
}
}
}
return intro + exception + classesStackString;
}
}