package net.curisit.securis.utils; import java.io.InputStream; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.curisit.securis.SeCurisException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * Retrieve HW info * * @author cesarcalvo * */ public class HWInfo { private static final Logger log = LogManager.getLogger(HWInfo.class); public static String getOsName() { return System.getProperty("os.name"); } public static String getArch() { return System.getProperty("os.arch"); } public static int getNumCpus() { return Runtime.getRuntime().availableProcessors(); } /** * Gets MAC address using Java. Java does not show information about down interfaces * * @return */ public static List getMACAddress() throws SeCurisException { log.info("Retrieving HW info with Java VM"); List macs = new ArrayList(); try { for (NetworkInterface network : Collections.list(NetworkInterface.getNetworkInterfaces())) { if (!network.isLoopback() && !network.isVirtual() && !network.isPointToPoint() && network.getHardwareAddress() != null) { macs.add(network.getHardwareAddress()); log.debug("Interface added {}, MAC: {}", network.getName(), network.getHardwareAddress()); logInterface(network); } } if (macs.isEmpty()) { throw new SeCurisException("Unable to get MAC address"); } List macAddresses = new ArrayList(); for (byte[] mac : macs) { macAddresses.add(printMacAddress(mac)); } log.info("MAC Addresses: {}", macAddresses); return macAddresses; } catch (Exception e) { throw new SeCurisException("Unable to get MAC address", e); } } /** * Gets MAC address natively using ipconfig or ifconfig. * @return * @throws CurisException */ public static List getMACAddressNatively() throws SeCurisException { try { log.info("Retrieving HW info natively"); String output; if (isWindows()) { output = executeCommand(new String[] {"ipconfig", "/all"}); } else { output = executeCommand(new String[] {"ifconfig", "-a"}); } //String output = FileUtils.readFileToString(new File("/Users/cesar/Downloads/ipconfig_no_mac.txt"), "UTF-8"); log.debug("Command output {}", output); List macs = extractMacs(output); log.debug("Macs found: {}", macs); return macs; } catch (SeCurisException ce) { throw ce; } } /** * Tries to retrieve MAC address natively, if it fails then it tries to retrieve it using Java * @return * @throws CurisException */ public static List getMACAddressNativelyFailback() throws SeCurisException { try { return getMACAddressNatively(); } catch (SeCurisException e) { log.info("Error getting HW info natively" .concat(e.getMessage())); return getMACAddress(); } } /** * Finds MAC in a string. Match string like this: * Unix: 60:03:08:95:ae:d0 * Windows: 0A-00-27-00-00-00 * * @param line * @return * @throws CurisException */ private static List extractMacs(String line) throws SeCurisException { Pattern pattern = Pattern.compile("(?m)( )([0-9a-fA-F][0-9a-fA-F][:-]){5}([0-9a-fA-F][0-9a-fA-F])($| )"); List macs = new ArrayList<>(); Matcher matcher = pattern.matcher(line); while(matcher.find()){ String mac = matcher.group().trim().replaceAll(":", "-").toUpperCase(); if (!mac.equals("00-00-00-00-00-00")) { macs.add(mac); } } if (macs.isEmpty()) { throw new SeCurisException("Mac is not found"); } return macs; } /** * Executes the given command and return the standard output. * @param command * @return * @throws Exception */ private static String executeCommand(String[] command) throws SeCurisException { try { Process process = new ProcessBuilder(command).start(); InputStream is = process.getInputStream(); String output = IOUtils.toString(is, "UTF-8"); if (process == null || process.exitValue() != 0) { throw new SeCurisException(String.format("Error executing command %s", StringUtils.join(command, " "))); } return output; } catch (Exception e) { throw new SeCurisException(String.format("Error executing command %s", StringUtils.join(command, " ")), e); } } /** * Returns true is OOSS is windows * @return */ public static boolean isWindows() { String os = System.getProperty("os.name").toLowerCase(); return (os.indexOf("win") >= 0); } /** * Get microprocessor name * * @return */ public static String getCPUName() throws SeCurisException { return System.getenv("PROCESSOR_IDENTIFIER"); } private static void logInterface(NetworkInterface network) { log.debug("Interface name: {}", network.getName()); log.debug("Interface display name: {}", network.getDisplayName()); try { log.debug("Interface mac: {}", printMacAddress(network.getHardwareAddress())); } catch (SocketException e) { // Silent } } private static String printMacAddress(byte[] mac) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < mac.length; i++) { sb.append(String.format("%s%02X", (i > 0) ? "-" : "", mac[i])); } return sb.toString(); } }