package org.owasp.security.logging.layout.rich; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.Manifest; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import ch.qos.logback.classic.spi.LoggingEvent; public class RichContext { private long pid; private long clientTime; private String applicationName; private String inetAddress; public RichContext(LoggingEvent event) { pid = getPID(); clientTime = event.getTimeStamp(); applicationName = getApplicationName(); inetAddress = getLocalHostLANAddress(); } public static long getPID() { String processName = java.lang.management.ManagementFactory .getRuntimeMXBean().getName(); return Long.parseLong(processName.split("@")[0]); } public String getApplicationName() { try (InputStream manifestStream = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("META-INF/MANIFEST.MF")) { Manifest manifest = new Manifest(manifestStream); Attributes attrs = manifest.getMainAttributes(); // does this work for all java applications ? String appName = attrs.getValue("Implementation-Title"); if (appName == null) { appName = "UNKNOWN"; } return appName; } catch (IOException E) { // handle } return null; } public static String getHMAC(String msg) { String macKey = System.getProperty("hmac.key", "HMAC KEY"); Mac mac; char[] checksum = "<unknown HMAC>".toCharArray(); try { mac = Mac.getInstance("HmacSHA256"); // get the bytes of the hmac key and data string byte[] secretByte = macKey.getBytes("UTF-8"); byte[] dataBytes = msg.getBytes("UTF-8"); SecretKey secret = new SecretKeySpec(secretByte, "HMACSHA256"); mac.init(secret); byte[] doFinal = mac.doFinal(dataBytes); checksum = Hex.encodeHex(doFinal); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return String.copyValueOf(checksum); } private static String getLocalHostLANAddress() { try { InetAddress candidateAddress = null; // Iterate all NICs (network interface cards)... for (Enumeration<NetworkInterface> ifaces = NetworkInterface .getNetworkInterfaces(); ifaces.hasMoreElements();) { NetworkInterface iface = (NetworkInterface) ifaces .nextElement(); // Iterate all IP addresses assigned to each card... for (Enumeration<InetAddress> inetAddrs = iface .getInetAddresses(); inetAddrs.hasMoreElements();) { InetAddress inetAddr = (InetAddress) inetAddrs .nextElement(); if (!inetAddr.isLoopbackAddress()) { if (inetAddr.isSiteLocalAddress()) { return inetAddr.toString(); } else if (candidateAddress == null) { candidateAddress = inetAddr; } } } } if (candidateAddress != null) { return candidateAddress.toString(); } InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); if (jdkSuppliedAddress == null) { throw new UnknownHostException( "The JDK InetAddress.getLocalHost() method unexpectedly returned null."); } return jdkSuppliedAddress.toString(); } catch (Exception e) { return "<unknown ip>"; } } @Override public String toString() { String message = "[pid=" + pid + ", applicationName=" + applicationName + ", clientTime=" + clientTime + ", clientIp=" + inetAddress + "]"; String signedMessage = message + getHMAC(message); return signedMessage; } }