// // Copyright (c) 2005 PortWise AB. All rights reserved. // // This software is the confidential and proprietary information of PortWise // AB. ("Confidential Information"). You shall not disclose such Confidential // Information and shall use it only in accordance with the terms of the // agreement you entered into with PortWise AB. // // Warning: This computer program is protected by copyright law and // international treaties. Unauthorized reproduction or distribution of this // program, or any portion of it, may result in severe civil and criminal // penalties, and will be prosecuted to the maximum extent possible under law. // package com.portwise.xpi.epi.plugins.mac; import java.util.HashMap; import java.util.Locale; import java.util.Vector; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.portwise.core.plugins.plugin.BasePlugin; import com.portwise.core.plugins.plugin.PluginProperties; import com.portwise.xpi.epi.plugins.AssessPluginException; import com.portwise.xpi.epi.plugins.AssessPluginResult; import com.portwise.xpi.epi.plugins.AssessServerSettings; import com.portwise.xpi.epi.plugins.AssessTermInformation; import com.portwise.xpi.epi.plugins.ClientRegistry; import com.portwise.xpi.epi.plugins.IAssessPlugin; import com.portwise.xpi.epi.plugins.XMLDocument; /** * The plug-in retrieves the MAC address of the connecting client and validates the address against * a pre-defined list of authorized client MAC addresses. If an address match is identified in the * authorized MAC address list, the client is allowed access to the protected resource. If the * client's MAC address is not authorized, the request is rejected. * * @author PortWise AB */ public class AssessMACPlugin extends BasePlugin implements AssessMACPluginProperties, IAssessPlugin { /** Holds the settings supplied by the Policy Service describing the access rule. */ private PluginProperties mPluginProperties = null; /** * The plug-in needs an empty main method to be able to initialize the plugin. * * @param args System arguments. */ public static void main(String[] args) { // Nothing to do here } /** * @see com.portwise.core.plugins.plugin.IPlugin#getName() */ public String getName() { return "Assessment MAC Plugin"; } /** * @see com.portwise.core.plugins.plugin.IPlugin#getMajorVersion() */ public int getMajorVersion() { return 1; } /** * @see com.portwise.core.plugins.plugin.IPlugin#getMinorVersion() */ public int getMinorVersion() { return 0; } /** * @see com.portwise.core.plugins.plugin.BasePlugin#getDefaultsFile() */ protected String getDefaultsFile() { return "/com/portwise/xpi/epi/plugins/mac/defaults.properties"; } /** * @see com.portwise.core.plugins.plugin.BasePlugin#getLocaleFile() */ protected String getLocaleFile() { return "com.portwise.xpi.epi.plugins.mac.locale"; } /** * @see com.portwise.core.plugins.plugin.BasePlugin#getPropertyEnums() */ protected int[] getPropertyEnums() { return PROPERTY_ENUMS; } /** * @see com.portwise.core.plugins.plugin.IPlugin#getPropertyKeys() */ public String[] getPropertyKeys() { return PROPERTY_KEYS; } /** * @see com.portwise.core.plugins.plugin.IPlugin#isPropertyRequired(java.lang.String) */ public boolean isPropertyRequired(String propertyKey) { // When configuring the plug-in in the administrator this method will decide if the // properties should be required or not. In this example only the MAC address property // is required. switch (getPropertyEnum(propertyKey)) { case ENUM_MAC_ADDRESSES : return true; case ENUM_USE_DEFAULT_MESSAGE : return false; case ENUM_DEFAULT_MESSAGE : return false; default : return false; } } /** * @see com.portwise.core.plugins.plugin.IPlugin#testProperties(com.portwise.core.plugins.plugin.PluginProperties, * java.util.Locale) */ public HashMap testProperties(PluginProperties properties, Locale locale) { // Nothing to test here HashMap errors = new HashMap(); return errors; } /** * @see com.portwise.core.plugins.plugin.IPlugin#isPropertyAdvanced(java.lang.String) */ public boolean isPropertyAdvanced(String propertyKey) { // None of the properties are advanced so always return false return false; } /** * @see com.portwise.core.plugins.plugin.IPlugin#getPropertyMin(java.lang.String) */ public int getPropertyMin(String propertyKey) { // None of the properties in the example have a min value. // Use this method for numeric property types. switch (getPropertyEnum(propertyKey)) { default : return 0; } } /** * @see com.portwise.core.plugins.plugin.IPlugin#getPropertyMax(java.lang.String) */ public int getPropertyMax(String propertyKey) { // None of the properties in the example have a max value. // Use this method for numeric property types. switch (getPropertyEnum(propertyKey)) { default : return Integer.MAX_VALUE; } } /** * @see com.portwise.core.plugins.plugin.IPlugin#getPropertySelectValues(java.lang.String) */ public String[] getPropertySelectValues(String propertyKey) { // The sample plug-in doesn't have any select lists in the property list, so we // return null. switch (getPropertyEnum(propertyKey)) { default : return null; } } /** * @see com.portwise.core.plugins.plugin.IPlugin#getPropertyType(java.lang.String) */ public int getPropertyType(String propertyKey) { // Return the type of the current property defined by the property key. switch (getPropertyEnum(propertyKey)) { case ENUM_MAC_ADDRESSES : return PluginProperties.PRP_TYPE_STRING; case ENUM_USE_DEFAULT_MESSAGE : return PluginProperties.PRP_TYPE_BOOLEAN; case ENUM_DEFAULT_MESSAGE : return PluginProperties.PRP_TYPE_TEXT; default : return PluginProperties.PRP_TYPE_STRING; } } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#addClientInfoCollectors(com.portwise.xpi.epi.plugins.XMLDocument) */ public AssessPluginResult addClientInfoCollectors(XMLDocument document) throws AssessPluginException { // The plugin require the client scan to return network information. // The key in ServerPolicy.xml is // ServerPolicy.Windows.Policy.Assessment.General.CollectNetworkInfo.Active. // We must verify that the key is active. If it isn't, then we have to change the value in // the policy document. // This method is called just before the policy document is sent to the client for scanning. info(getName() + ": addClientInfoCollectors"); try { HashMap attributes = new HashMap(); String c; // Copy network attribute from existing settings and add our required c = document .getValueForKey("ServerPolicy.Windows.Policy.Assessment.General.CollectNetworkInfo.Active"); if (c != null) { // Set the flag to true c = "true"; attributes.put("Active", c); document.createElementWithAttributes( "ServerPolicy.Windows.Policy.Assessment.General.CollectNetworkInfo.", attributes, true); } // Copy windows attribute from existing settings and add our required c = document .getValueForKey("ServerPolicy.Windows.Policy.Assessment.General.CollectWindowsInfo.Active"); if (c != null) { // Set the flag to true c = "true"; attributes.put("Active", c); document.createElementWithAttributes( "ServerPolicy.Windows.Policy.Assessment.General.CollectWindowsInfo.", attributes, true); } } catch (Exception e) { return new AssessPluginResult("Plugin failed to add client collector", "Plugin could not add requirements needed"); } return new AssessPluginResult(); } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#onAccessResource(com.portwise.xpi.epi.plugins.ClientRegistry, * com.portwise.xpi.epi.plugins.AssessTermInformation, java.lang.String) */ public AssessPluginResult onAccessResource(ClientRegistry clientRegistry, AssessTermInformation accessRule, String uri) throws AssessPluginException { info(getName() + ": onAccessResource"); // Get network and domain info from the client scan data Vector clientData = clientRegistry .getNodesForKey("ClientRegistry.Windows.NetworkInterface"); Vector clientDataDomain = clientRegistry .getNodesForKey("ClientRegistry.Windows.WindowsDomain"); String domValue = null; if (clientDataDomain != null && clientDataDomain.size() > 0) { NamedNodeMap domMap = ((Node) clientDataDomain.firstElement()).getAttributes(); domValue = domMap.getNamedItem("langroup").getNodeValue(); } // Get the value configured by the PortWise Administrator String authorizeAddresses = mPluginProperties.getString( AssessMACPluginProperties.MAC_ADDRESSES, ""); int vSize; if (clientData != null && authorizeAddresses != null) { // Create a new handler that will do the matching AccessHandler addressAuthorizer = new AccessHandler(authorizeAddresses); vSize = clientData.size(); String value = null; // For all network interfaces for (int j = 0; j < vSize; j++) { // Get the clients physical address NamedNodeMap map = ((Node) clientData.elementAt(j)).getAttributes(); value = map.getNamedItem("physicalAddr").getNodeValue(); if (value.equals("N/A") && j != (vSize - 1)) { continue; } info("AssessMACPlugin message: Access Attempt by client MAC: " + value); if (domValue != null) info("AssessMACPlugin message: client belongs to Lan group Domain: " + domValue); else info("AssessMACPlugin message: Plugin failed to retrive client Domain"); // Verify the end-user's MAC address against the list of valid addresses if (addressAuthorizer.checkAccess(value)) return new AssessPluginResult(); } } // The user did not have access to the resource. // Returning a new AssessPluginResult object with the error messages. // The first argument is logged to the system log, the second argument // is displayed to the end user. String logMessage = "Assessment MAC Plugin error message"; return new AssessPluginResult(logMessage, getEndUserMessage(logMessage)); } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#onLoad(com.portwise.xpi.epi.plugins.AssessServerSettings, * com.portwise.core.plugins.plugin.PluginProperties) */ public AssessPluginResult onLoad(AssessServerSettings serverSettings, PluginProperties environmentSettings) throws AssessPluginException { // Save the properties supplied by the policy service in a local // variable so we can use the information later. info(getName() + ": onLoad"); mPluginProperties = environmentSettings; return new AssessPluginResult(); } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#onUnload() */ public AssessPluginResult onUnload() throws AssessPluginException { // Never called in PortWise 4.5 info(getName() + ": onUnload"); return new AssessPluginResult(); } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#onUpdate(com.portwise.xpi.epi.plugins.ClientRegistry) */ public AssessPluginResult onUpdate(ClientRegistry clientRegistry) throws AssessPluginException { // Never called in PortWise 4.5 info(getName() + ": onUpdate"); return new AssessPluginResult(); } /** * @see com.portwise.xpi.epi.plugins.IAssessPlugin#onVerify(com.portwise.xpi.epi.plugins.ClientRegistry, * java.lang.String, java.lang.String) */ public AssessPluginResult onVerify(ClientRegistry clientRegistry, String sessionId, String username) throws AssessPluginException { // Always return true when the user sends client data otherwise will the authentication fail info(getName() + ": onVerify"); return new AssessPluginResult(); } /** * Method for getting the message that should be displayed for the end user. The message * displayed is the same as the log message, if not property USER_DEFAULT_MESSAGE is set. Then * the default message is used. * * @param logMessage Log message * @return End user message */ private String getEndUserMessage(String logMessage) { if (mPluginProperties.getBoolean(AssessMACPluginProperties.USE_DEFAULT_MESSAGE, false)) { return mPluginProperties.getString(AssessMACPluginProperties.DEFAULT_MESSAGE, ""); } return logMessage; } }