//
// 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;
}
}