Refactor provisioning.

cusax-fix
Sebastien Vincent 14 years ago
parent b48863e19b
commit 2bcf9fe2de

@ -2624,6 +2624,8 @@ javax.swing.event, javax.swing.border"/>
manifest="${src}/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/plugin/provisioning"
prefix="net/java/sip/communicator/plugin/provisioning" />
<zipfileset dir="${dest}/net/java/sip/communicator/service/provisioning"
prefix="net/java/sip/communicator/service/provisioning" />
</jar>
</target>

@ -6,23 +6,16 @@
*/
package net.java.sip.communicator.plugin.provisioning;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List; //disambiguation
import javax.swing.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.credentialsstorage.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.httputil.*;
import net.java.sip.communicator.service.netaddr.*;
import net.java.sip.communicator.service.provdisc.*;
import net.java.sip.communicator.service.provisioning.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import org.osgi.framework.*;
@ -33,7 +26,7 @@
*/
public class ProvisioningActivator
implements BundleActivator
{
{
/**
* Logger of this class
*/
@ -45,54 +38,6 @@ public class ProvisioningActivator
*/
private static BundleContext bundleContext = null;
/**
* Name of the provisioning URL in the configuration service.
*/
private static final String PROPERTY_PROVISIONING_URL
= "net.java.sip.communicator.plugin.provisioning.URL";
/**
* Name of the provisioning username in the configuration service
* authentication).
*/
static final String PROPERTY_PROVISIONING_USERNAME
= "net.java.sip.communicator.plugin.provisioning.auth.USERNAME";
/**
* Name of the provisioning password in the configuration service (HTTP
* authentication).
*/
static final String PROPERTY_PROVISIONING_PASSWORD
= "net.java.sip.communicator.plugin.provisioning.auth";
/**
* Name of the property that contains the provisioning method (i.e. DHCP,
* DNS, manual, ...).
*/
private static final String PROVISIONING_METHOD_PROP
= "net.java.sip.communicator.plugin.provisioning.METHOD";
/**
* Name of the property that contains enforce prefix list (separated by
* pipe) for the provisioning. The retrieved configuration properties will
* be checked against these prefixes to avoid having incorrect content in
* the configuration file (such as HTML content resulting of HTTP error).
*/
private static final String PROVISIONING_ALLOW_PREFIX_PROP
= "provisioning.ALLOW_PREFIX";
/**
* Name of the enforce prefix property.
*/
private static final String PROVISIONING_ENFORCE_PREFIX_PROP
= "provisioning.ENFORCE_PREFIX";
/**
* Name of the UUID property.
*/
public static final String PROVISIONING_UUID_PROP
= "net.java.sip.communicator.UUID";
/**
* A reference to the ConfigurationService implementation instance that
* is currently registered with the bundle context.
@ -120,11 +65,11 @@ public class ProvisioningActivator
* The resource service.
*/
private static ResourceManagementService resourceService;
/**
* List of allowed configuration prefixes.
* Provisioning service.
*/
private List<String> allowedPrefixes = new ArrayList<String>();
private static ProvisioningServiceImpl provisioningService = null;
/**
* Starts this bundle
@ -134,21 +79,13 @@ public class ProvisioningActivator
*/
public void start(BundleContext bundleContext) throws Exception
{
String url = null;
if (logger.isDebugEnabled())
logger.debug("Provisioning discovery [STARTED]");
ProvisioningActivator.bundleContext = bundleContext;
String uuid = (String)getConfigurationService().getProperty(
PROVISIONING_UUID_PROP);
if(uuid == null || uuid.equals(""))
{
uuid = UUID.randomUUID().toString();
getConfigurationService().setProperty(PROVISIONING_UUID_PROP, uuid);
}
String url = null;
provisioningService = new ProvisioningServiceImpl();
Dictionary<String, String> properties = new Hashtable<String, String>();
properties.put( ConfigurationForm.FORM_TYPE,
@ -164,7 +101,7 @@ public void start(BundleContext bundleContext) throws Exception
2000, true),
properties);
String method = getProvisioningMethod();
String method = provisioningService.getProvisioningMethod();
if(method == null || method.equals("NONE"))
{
@ -193,28 +130,11 @@ public void start(BundleContext bundleContext) throws Exception
}
}
}
if(url == null)
{
/* try to see if provisioning URL is stored in properties */
url = getProvisioningUri();
}
if(url != null)
{
File file = retrieveConfigurationFile(url);
if(file != null)
{
/* store the provisioning URL in local configuration in case
* the provisioning discovery failed (DHCP/DNS unavailable, ...)
*/
getConfigurationService().setProperty(
PROPERTY_PROVISIONING_URL, url);
updateConfiguration(file);
}
}
provisioningService.start(url);
bundleContext.registerService(
ProvisioningService.class.getName(), provisioningService, null);
if (logger.isDebugEnabled())
logger.debug("Provisioning discovery [REGISTERED]");
@ -234,73 +154,6 @@ public void stop(BundleContext bundleContext) throws Exception
logger.debug("Provisioning discovery [STOPPED]");
}
/**
* Indicates if the provisioning has been enabled.
*
* @return <tt>true</tt> if the provisioning is enabled, <tt>false</tt> -
* otherwise
*/
public static String getProvisioningMethod()
{
String provMethod
= getConfigurationService().getString(PROVISIONING_METHOD_PROP);
if (provMethod == null || provMethod.length() <= 0)
{
provMethod = getResourceService().getSettingsString(
"plugin.provisioning.DEFAULT_PROVISIONING_METHOD");
if (provMethod != null && provMethod.length() > 0)
setProvisioningMethod(provMethod);
}
return provMethod;
}
/**
* Enables the provisioning with the given method. If the provisioningMethod
* is null disables the provisioning.
*
* @param provisioningMethod the provisioning method
*/
public static void setProvisioningMethod(String provisioningMethod)
{
getConfigurationService().setProperty(
PROVISIONING_METHOD_PROP, provisioningMethod);
}
/**
* Returns the provisioning URI.
*
* @return the provisioning URI
*/
public static String getProvisioningUri()
{
String provUri
= getConfigurationService().getString(PROPERTY_PROVISIONING_URL);
if (provUri == null || provUri.length() <= 0)
{
provUri = getResourceService().getSettingsString(
"plugin.provisioning.DEFAULT_PROVISIONING_URI");
if (provUri != null && provUri.length() > 0)
setProvisioningUri(provUri);
}
return provUri;
}
/**
* Sets the provisioning URI.
*
* @param uri the provisioning URI to set
*/
public static void setProvisioningUri(String uri)
{
getConfigurationService().setProperty(
PROPERTY_PROVISIONING_URL, uri);
}
/**
* Returns the <tt>UIService</tt> obtained from the bundle context.
*
@ -344,426 +197,6 @@ public static ResourceManagementService getResourceService()
return resourceService;
}
/**
* Retrieve configuration file from provisioning URL.
* This method is blocking until configuration file is retrieved from the
* network or if an exception happen
*
* @param url provisioning URL
* @return provisioning file downloaded
*/
private File retrieveConfigurationFile(String url)
{
File tmpFile = null;
try
{
String arg = null;
String args[] = null;
final File temp = File.createTempFile("provisioning",
".properties");
tmpFile = temp;
URL u = new URL(url);
InetAddress ipaddr = getNetworkAddressManagerService().
getLocalHost(InetAddress.getByName(u.getHost()));
if(url.indexOf("${uuid}") != -1)
{
url = url.replace("${uuid}", (String)getConfigurationService()
.getProperty(PROVISIONING_UUID_PROP));
}
if(url.indexOf("${osname}") != -1)
{
url = url.replace("${osname}", System.getProperty("os.name"));
}
if(url.indexOf("${arch}") != -1)
{
url = url.replace("${arch}", System.getProperty("os.arch"));
}
if(url.indexOf("${resx}") != -1 || url.indexOf("${resy}") != -1)
{
Rectangle screen = ScreenInformation.getScreenBounds();
if(url.indexOf("${resx}") != -1)
{
url = url.replace("${resx}", String.valueOf(screen.width));
}
if(url.indexOf("${resy}") != -1)
{
url = url.replace("${resy}", String.valueOf(screen.height));
}
}
if(url.indexOf("${build}") != -1)
{
url = url.replace("${build}",
System.getProperty("sip-communicator.version"));
}
if(url.indexOf("${ipaddr}") != -1)
{
url = url.replace("${ipaddr}", ipaddr.getHostAddress());
}
if(url.indexOf("${hwaddr}") != -1)
{
if(ipaddr != null)
{
/* find the hardware address of the interface
* that has this IP address
*/
Enumeration<NetworkInterface> en =
NetworkInterface.getNetworkInterfaces();
while(en.hasMoreElements())
{
NetworkInterface iface = en.nextElement();
Enumeration<InetAddress> enInet =
iface.getInetAddresses();
while(enInet.hasMoreElements())
{
InetAddress inet = enInet.nextElement();
if(inet.equals(ipaddr))
{
byte hw[] =
getNetworkAddressManagerService().
getHardwareAddress(iface);
if(hw == null)
continue;
StringBuffer buf =
new StringBuffer();
for(byte h : hw)
{
int hi = h >= 0 ? h : h + 256;
String t = new String(
(hi <= 0xf) ? "0" : "");
t += Integer.toHexString(hi);
buf.append(t);
buf.append(":");
}
buf.deleteCharAt(buf.length() - 1);
url = url.replace("${hwaddr}",
buf.toString());
break;
}
}
}
}
}
if(url.contains("?"))
{
/* do not handle URL of type http://domain/index.php? (no
* parameters)
*/
if((url.indexOf('?') + 1) != url.length())
{
arg = url.substring(url.indexOf('?') + 1);
args = arg.split("&");
}
url = url.substring(0, url.indexOf('?'));
}
String[] paramNames = null;
String[] paramValues = null;
int usernameIx = -1;
int passwordIx = -1;
if(args != null && args.length > 0)
{
paramNames = new String[args.length];
paramValues = new String[args.length];
for(int i = 0; i < args.length; i++)
{
String s = args[i];
String usernameParam = "${username}";
String passwordParam = "${password}";
// If we find the username or password parameter at this
// stage we replace it with an empty string.
if(s.indexOf(usernameParam) != -1)
{
s = s.replace(usernameParam, "");
usernameIx = i;
}
else if(s.indexOf(passwordParam) != -1)
{
s = s.replace(passwordParam, "");
passwordIx = i;
}
int equalsIndex = s.indexOf("=");
if (equalsIndex > 0)
{
paramNames[i] = s.substring(0, equalsIndex);
paramValues[i] = s.substring(equalsIndex + 1);
}
}
}
HttpUtils.HTTPResponseResult res =
HttpUtils.postForm(
url,
PROPERTY_PROVISIONING_USERNAME,
PROPERTY_PROVISIONING_PASSWORD,
paramNames,
paramValues,
usernameIx,
passwordIx);
// if there was an error in retrieving stop
if(res == null)
return null;
InputStream in = res.getContent();
// Chain a ProgressMonitorInputStream to the
// URLConnection's InputStream
final ProgressMonitorInputStream pin
= new ProgressMonitorInputStream(null, u.toString(), in);
// Set the maximum value of the ProgressMonitor
ProgressMonitor pm = pin.getProgressMonitor();
pm.setMaximum((int)res.getContentLength());
final BufferedOutputStream bout
= new BufferedOutputStream(new FileOutputStream(temp));
try
{
int read = -1;
byte[] buff = new byte[1024];
while((read = pin.read(buff)) != -1)
{
bout.write(buff, 0, read);
}
pin.close();
bout.flush();
bout.close();
return temp;
}
catch (Exception e)
{
logger.error("Error saving", e);
try
{
pin.close();
bout.close();
}
catch (Exception e1)
{
}
return null;
}
}
catch (Exception e)
{
if (logger.isInfoEnabled())
logger.info("Error retrieving provisioning file!", e);
tmpFile.delete();
return null;
}
}
/**
* Update configuration with properties retrieved from provisioning URL.
*
* @param file provisioning file
*/
private void updateConfiguration(final File file)
{
Properties fileProps = new OrderedProperties();
InputStream in = null;
try
{
in = new BufferedInputStream(new FileInputStream(file));
fileProps.load(in);
Iterator<Map.Entry<Object, Object> > it
= fileProps.entrySet().iterator();
while(it.hasNext())
{
Map.Entry<Object, Object> entry = it.next();
String key = (String)entry.getKey();
Object value = entry.getValue();
if(key.equals(PROVISIONING_ALLOW_PREFIX_PROP))
{
String prefixes[] = ((String)value).split("\\|");
/* updates allowed prefixes list */
for(String s : prefixes)
{
allowedPrefixes.add(s);
}
continue;
}
else if(key.equals(PROVISIONING_ENFORCE_PREFIX_PROP))
{
checkEnforcePrefix((String)value);
continue;
}
/* check that properties is allowed */
if(!isPrefixAllowed(key))
{
continue;
}
processProperty(key, value);
}
try
{
/* save and reload the "new" configuration */
getConfigurationService().storeConfiguration();
getConfigurationService().reloadConfiguration();
}
catch(Exception e)
{
logger.error("Cannot reload configuration");
}
}
catch(IOException e)
{
logger.warn("Error during load of provisioning file");
}
finally
{
try
{
in.close();
file.delete();
}
catch(IOException e)
{
}
}
}
/**
* Check if a property name belongs to the allowed prefixes.
*
* @param key property key name
* @return true if key is allowed, false otherwise
*/
private boolean isPrefixAllowed(String key)
{
if(allowedPrefixes.size() > 0)
{
for(String s : allowedPrefixes)
{
if(key.startsWith(s))
{
return true;
}
}
/* current property prefix is not allowed */
return false;
}
else
{
/* no allowed prefixes configured so key is valid by default */
return true;
}
}
/**
* Process a new property. If value equals "${null}", it means to remove the
* property in the configuration service. If the key name end with
* "PASSWORD", its value is encrypted through credentials storage service,
* otherwise the property is added/updated in the configuration service.
*
* @param key property key name
* @param value property value
*/
private void processProperty(String key, Object value)
{
if((value instanceof String) && ((String)value).equals("${null}"))
{
getConfigurationService().removeProperty(key);
}
else if(key.endsWith(".PASSWORD"))
{
/* password => credentials storage service */
getCredentialsStorageService().storePassword(
key.substring(0, key.lastIndexOf(".")),
(String)value);
}
else
{
getConfigurationService().setProperty(key, value);
}
}
/**
* Walk through all properties and make sure all properties keys match
* a specific set of prefixes defined in configuration.
*
* @param enforcePrefix list of enforce prefix.
*/
private void checkEnforcePrefix(String enforcePrefix)
{
ConfigurationService config = getConfigurationService();
String prefixes[] = null;
if(enforcePrefix == null)
{
return;
}
/* must escape the | character */
prefixes = enforcePrefix.split("\\|");
/* get all properties */
for (String key : config.getAllPropertyNames())
{
boolean isValid = false;
for(String k : prefixes)
{
if(key.startsWith(k))
{
isValid = true;
break;
}
}
/* property name does is not in the enforce prefix list
* so remove it
*/
if(!isValid)
{
config.removeProperty(key);
}
}
}
/**
* Returns a reference to a ConfigurationService implementation currently
* registered in the bundle context or null if no such implementation was
@ -827,4 +260,14 @@ public static NetworkAddressManagerService getNetworkAddressManagerService()
}
return netaddrService;
}
/**
* Returns a reference to a <tt>ProvisioningService</tt> implementation.
*
* @return a currently valid implementation of <tt>ProvisioningService</tt>
*/
public static ProvisioningServiceImpl getProvisioningService()
{
return provisioningService;
}
}

@ -169,7 +169,8 @@ public ProvisioningForm()
uuidPane.setEditable(false);
uuidPane.setOpaque(false);
uuidPane.setText(
config.getString(ProvisioningActivator.PROVISIONING_UUID_PROP));
config.getString(ProvisioningServiceImpl.
PROVISIONING_UUID_PROP));
uuidPanel.add(new JLabel(resources.getI18NString(
"plugin.provisioning.UUID")));
@ -276,7 +277,8 @@ public void actionPerformed(ActionEvent evt)
*/
private void initButtonStates()
{
String provMethod = ProvisioningActivator.getProvisioningMethod();
String provMethod = ProvisioningActivator.getProvisioningService().
getProvisioningMethod();
boolean isProvEnabled
= (provMethod != null
&& provMethod.length() > 0
@ -296,7 +298,8 @@ else if (provMethod.equals("Manual"))
{
manualButton.setSelected(true);
String uri = ProvisioningActivator.getProvisioningUri();
String uri = ProvisioningActivator.getProvisioningService().
getProvisioningUri();
if (uri != null)
uriField.setText(uri);
}
@ -311,16 +314,16 @@ else if (provMethod.equals("Manual"))
// creadentials
forgetPasswordButton.setEnabled(isProvEnabled);
usernameField.setText(ProvisioningActivator.getConfigurationService()
.getString(ProvisioningActivator.PROPERTY_PROVISIONING_USERNAME));
.getString(ProvisioningServiceImpl.PROPERTY_PROVISIONING_USERNAME));
if(ProvisioningActivator.getCredentialsStorageService()
.isStoredEncrypted(
ProvisioningActivator.PROPERTY_PROVISIONING_PASSWORD))
ProvisioningServiceImpl.PROPERTY_PROVISIONING_PASSWORD))
{
passwordField.setText(
ProvisioningActivator.getCredentialsStorageService()
.loadPassword(
ProvisioningActivator.PROPERTY_PROVISIONING_PASSWORD));
ProvisioningServiceImpl.PROPERTY_PROVISIONING_PASSWORD));
}
}
@ -367,8 +370,8 @@ else if (manualButton.isSelected())
}
}
ProvisioningActivator
.setProvisioningMethod(provisioningMethod);
ProvisioningActivator.getProvisioningService().
setProvisioningMethod(provisioningMethod);
}
});
@ -377,8 +380,8 @@ else if (manualButton.isSelected())
public void stateChanged(ChangeEvent e)
{
if (dhcpButton.isSelected())
ProvisioningActivator
.setProvisioningMethod("DHCP");
ProvisioningActivator.getProvisioningService().
setProvisioningMethod("DHCP");
}
});
@ -387,8 +390,8 @@ public void stateChanged(ChangeEvent e)
public void stateChanged(ChangeEvent e)
{
if (dnsButton.isSelected())
ProvisioningActivator
.setProvisioningMethod("DNS");
ProvisioningActivator.getProvisioningService().
setProvisioningMethod("DNS");
}
});
@ -397,8 +400,8 @@ public void stateChanged(ChangeEvent e)
public void stateChanged(ChangeEvent e)
{
if (bonjourButton.isSelected())
ProvisioningActivator
.setProvisioningMethod("Bonjour");
ProvisioningActivator.getProvisioningService().
setProvisioningMethod("Bonjour");
}
});
@ -412,15 +415,19 @@ public void stateChanged(ChangeEvent e)
if (isSelected)
{
ProvisioningActivator
.setProvisioningMethod("Manual");
ProvisioningActivator.getProvisioningService().
setProvisioningMethod("Manual");
String uriText = uriField.getText();
if (uriText != null && uriText.length() > 0)
ProvisioningActivator.setProvisioningUri(uriText);
ProvisioningActivator.getProvisioningService().
setProvisioningUri(uriText);
}
else
ProvisioningActivator.setProvisioningUri(null);
{
ProvisioningActivator.getProvisioningService().
setProvisioningUri(null);
}
}
});
@ -435,7 +442,8 @@ public void focusLost(FocusEvent e)
String uriText = uriField.getText();
if (uriText != null && uriText.length() > 0)
ProvisioningActivator.setProvisioningUri(uriText);
ProvisioningActivator.getProvisioningService().
setProvisioningUri(uriText);
}
public void focusGained(FocusEvent e) {}
@ -453,7 +461,8 @@ public void actionPerformed(ActionEvent actionEvent)
int result = JOptionPane.showConfirmDialog(
(Component)ProvisioningActivator.getUIService()
.getExportedWindow(ExportedWindow.MAIN_WINDOW).getSource(),
.getExportedWindow(ExportedWindow.MAIN_WINDOW).
getSource(),
ProvisioningActivator.getResourceService().getI18NString(
"plugin.provisioning.REMOVE_CREDENTIALS_MESSAGE"),
ProvisioningActivator.getResourceService().getI18NString(
@ -463,11 +472,11 @@ public void actionPerformed(ActionEvent actionEvent)
if (result == JOptionPane.YES_OPTION)
{
ProvisioningActivator.getCredentialsStorageService()
.removePassword(
ProvisioningActivator.PROPERTY_PROVISIONING_PASSWORD);
.removePassword(ProvisioningServiceImpl.
PROPERTY_PROVISIONING_PASSWORD);
ProvisioningActivator.getConfigurationService()
.removeProperty(
ProvisioningActivator.PROPERTY_PROVISIONING_USERNAME);
.removeProperty(ProvisioningServiceImpl.
PROPERTY_PROVISIONING_USERNAME);
usernameField.setText("");
passwordField.setText("");

@ -0,0 +1,667 @@
package net.java.sip.communicator.plugin.provisioning;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List; // disambiguation
import javax.swing.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.httputil.*;
import net.java.sip.communicator.service.provisioning.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
/**
* Provisioning service.
*
* @author Sebastien Vincent
*/
public class ProvisioningServiceImpl
implements ProvisioningService
{
/**
* Logger of this class
*/
private static final Logger logger
= Logger.getLogger(ProvisioningServiceImpl.class);
/**
* Name of the UUID property.
*/
public static final String PROVISIONING_UUID_PROP
= "net.java.sip.communicator.UUID";
/**
* Name of the provisioning URL in the configuration service.
*/
private static final String PROPERTY_PROVISIONING_URL
= "net.java.sip.communicator.plugin.provisioning.URL";
/**
* Name of the provisioning username in the configuration service
* authentication).
*/
static final String PROPERTY_PROVISIONING_USERNAME
= "net.java.sip.communicator.plugin.provisioning.auth.USERNAME";
/**
* Name of the provisioning password in the configuration service (HTTP
* authentication).
*/
static final String PROPERTY_PROVISIONING_PASSWORD
= "net.java.sip.communicator.plugin.provisioning.auth";
/**
* Name of the property that contains the provisioning method (i.e. DHCP,
* DNS, manual, ...).
*/
private static final String PROVISIONING_METHOD_PROP
= "net.java.sip.communicator.plugin.provisioning.METHOD";
/**
* Name of the property that contains enforce prefix list (separated by
* pipe) for the provisioning. The retrieved configuration properties will
* be checked against these prefixes to avoid having incorrect content in
* the configuration file (such as HTML content resulting of HTTP error).
*/
private static final String PROVISIONING_ALLOW_PREFIX_PROP
= "provisioning.ALLOW_PREFIX";
/**
* Name of the enforce prefix property.
*/
private static final String PROVISIONING_ENFORCE_PREFIX_PROP
= "provisioning.ENFORCE_PREFIX";
/**
* List of allowed configuration prefixes.
*/
private List<String> allowedPrefixes = new ArrayList<String>();
/**
* Authentication username.
*/
private static String provUsername = null;
/**
* Authentication password.
*/
private static String provPassword = null;
/**
* Constructor.
*/
public ProvisioningServiceImpl()
{
// check if UUID is already configured
String uuid = (String)ProvisioningActivator.getConfigurationService().
getProperty(PROVISIONING_UUID_PROP);
if(uuid == null || uuid.equals(""))
{
uuid = UUID.randomUUID().toString();
ProvisioningActivator.getConfigurationService().setProperty(
PROVISIONING_UUID_PROP, uuid);
}
}
/**
* Starts provisioning.
*
* @param url provisioning URL
*/
void start(String url)
{
if(url == null)
{
/* try to see if provisioning URL is stored in properties */
url = getProvisioningUri();
}
if(url != null)
{
File file = retrieveConfigurationFile(url);
if(file != null)
{
/* store the provisioning URL in local configuration in case
* the provisioning discovery failed (DHCP/DNS unavailable, ...)
*/
ProvisioningActivator.getConfigurationService().setProperty(
PROPERTY_PROVISIONING_URL, url);
updateConfiguration(file);
}
}
}
/**
* Indicates if the provisioning has been enabled.
*
* @return <tt>true</tt> if the provisioning is enabled, <tt>false</tt> -
* otherwise
*/
public String getProvisioningMethod()
{
String provMethod
= ProvisioningActivator.getConfigurationService().getString(
PROVISIONING_METHOD_PROP);
if (provMethod == null || provMethod.length() <= 0)
{
provMethod = ProvisioningActivator.getResourceService().
getSettingsString(
"plugin.provisioning.DEFAULT_PROVISIONING_METHOD");
if (provMethod != null && provMethod.length() > 0)
setProvisioningMethod(provMethod);
}
return provMethod;
}
/**
* Enables the provisioning with the given method. If the provisioningMethod
* is null disables the provisioning.
*
* @param provisioningMethod the provisioning method
*/
public void setProvisioningMethod(String provisioningMethod)
{
ProvisioningActivator.getConfigurationService().setProperty(
PROVISIONING_METHOD_PROP, provisioningMethod);
}
/**
* Returns the provisioning URI.
*
* @return the provisioning URI
*/
public String getProvisioningUri()
{
String provUri
= ProvisioningActivator.getConfigurationService().getString(
PROPERTY_PROVISIONING_URL);
if (provUri == null || provUri.length() <= 0)
{
provUri = ProvisioningActivator.getResourceService().
getSettingsString(
"plugin.provisioning.DEFAULT_PROVISIONING_URI");
if (provUri != null && provUri.length() > 0)
setProvisioningUri(provUri);
}
return provUri;
}
/**
* Sets the provisioning URI.
*
* @param uri the provisioning URI to set
*/
public void setProvisioningUri(String uri)
{
ProvisioningActivator.getConfigurationService().setProperty(
PROPERTY_PROVISIONING_URL, uri);
}
/**
* Returns provisioning username.
*
* @return provisioning username
*/
public String getProvisioningUsername()
{
return provUsername;
}
/**
* Returns provisioning password.
*
* @return provisioning password
*/
public String getProvisioningPassword()
{
return provPassword;
}
/**
* Retrieve configuration file from provisioning URL.
* This method is blocking until configuration file is retrieved from the
* network or if an exception happen
*
* @param url provisioning URL
* @return provisioning file downloaded
*/
private File retrieveConfigurationFile(String url)
{
File tmpFile = null;
try
{
String arg = null;
String args[] = null;
final File temp = File.createTempFile("provisioning",
".properties");
tmpFile = temp;
URL u = new URL(url);
InetAddress ipaddr =
ProvisioningActivator.getNetworkAddressManagerService().
getLocalHost(InetAddress.getByName(u.getHost()));
if(url.indexOf("${uuid}") != -1)
{
url = url.replace("${uuid}",
(String)ProvisioningActivator.getConfigurationService()
.getProperty(PROVISIONING_UUID_PROP));
}
if(url.indexOf("${osname}") != -1)
{
url = url.replace("${osname}", System.getProperty("os.name"));
}
if(url.indexOf("${arch}") != -1)
{
url = url.replace("${arch}", System.getProperty("os.arch"));
}
if(url.indexOf("${resx}") != -1 || url.indexOf("${resy}") != -1)
{
Rectangle screen = ScreenInformation.getScreenBounds();
if(url.indexOf("${resx}") != -1)
{
url = url.replace("${resx}", String.valueOf(screen.width));
}
if(url.indexOf("${resy}") != -1)
{
url = url.replace("${resy}", String.valueOf(screen.height));
}
}
if(url.indexOf("${build}") != -1)
{
url = url.replace("${build}",
System.getProperty("sip-communicator.version"));
}
if(url.indexOf("${ipaddr}") != -1)
{
url = url.replace("${ipaddr}", ipaddr.getHostAddress());
}
if(url.indexOf("${hwaddr}") != -1)
{
if(ipaddr != null)
{
/* find the hardware address of the interface
* that has this IP address
*/
Enumeration<NetworkInterface> en =
NetworkInterface.getNetworkInterfaces();
while(en.hasMoreElements())
{
NetworkInterface iface = en.nextElement();
Enumeration<InetAddress> enInet =
iface.getInetAddresses();
while(enInet.hasMoreElements())
{
InetAddress inet = enInet.nextElement();
if(inet.equals(ipaddr))
{
byte hw[] =
ProvisioningActivator.
getNetworkAddressManagerService().
getHardwareAddress(iface);
if(hw == null)
continue;
StringBuffer buf =
new StringBuffer();
for(byte h : hw)
{
int hi = h >= 0 ? h : h + 256;
String t = new String(
(hi <= 0xf) ? "0" : "");
t += Integer.toHexString(hi);
buf.append(t);
buf.append(":");
}
buf.deleteCharAt(buf.length() - 1);
url = url.replace("${hwaddr}",
buf.toString());
break;
}
}
}
}
}
if(url.contains("?"))
{
/* do not handle URL of type http://domain/index.php? (no
* parameters)
*/
if((url.indexOf('?') + 1) != url.length())
{
arg = url.substring(url.indexOf('?') + 1);
args = arg.split("&");
}
url = url.substring(0, url.indexOf('?'));
}
String[] paramNames = null;
String[] paramValues = null;
int usernameIx = -1;
int passwordIx = -1;
if(args != null && args.length > 0)
{
paramNames = new String[args.length];
paramValues = new String[args.length];
for(int i = 0; i < args.length; i++)
{
String s = args[i];
String usernameParam = "${username}";
String passwordParam = "${password}";
// If we find the username or password parameter at this
// stage we replace it with an empty string.
if(s.indexOf(usernameParam) != -1)
{
s = s.replace(usernameParam, "");
usernameIx = i;
}
else if(s.indexOf(passwordParam) != -1)
{
s = s.replace(passwordParam, "");
passwordIx = i;
}
int equalsIndex = s.indexOf("=");
if (equalsIndex > 0)
{
paramNames[i] = s.substring(0, equalsIndex);
paramValues[i] = s.substring(equalsIndex + 1);
}
}
}
HttpUtils.HTTPResponseResult res =
HttpUtils.postForm(
url,
PROPERTY_PROVISIONING_USERNAME,
PROPERTY_PROVISIONING_PASSWORD,
paramNames,
paramValues,
usernameIx,
passwordIx);
// if there was an error in retrieving stop
if(res == null)
return null;
String userPass[] = res.getCredentials();
if(userPass[0] != null && userPass[1] != null)
{
provUsername = userPass[0];
provPassword = userPass[1];
}
InputStream in = res.getContent();
// Chain a ProgressMonitorInputStream to the
// URLConnection's InputStream
final ProgressMonitorInputStream pin
= new ProgressMonitorInputStream(null, u.toString(), in);
// Set the maximum value of the ProgressMonitor
ProgressMonitor pm = pin.getProgressMonitor();
pm.setMaximum((int)res.getContentLength());
final BufferedOutputStream bout
= new BufferedOutputStream(new FileOutputStream(temp));
try
{
int read = -1;
byte[] buff = new byte[1024];
while((read = pin.read(buff)) != -1)
{
bout.write(buff, 0, read);
}
pin.close();
bout.flush();
bout.close();
return temp;
}
catch (Exception e)
{
logger.error("Error saving", e);
try
{
pin.close();
bout.close();
}
catch (Exception e1)
{
}
return null;
}
}
catch (Exception e)
{
if (logger.isInfoEnabled())
logger.info("Error retrieving provisioning file!", e);
tmpFile.delete();
return null;
}
}
/**
* Update configuration with properties retrieved from provisioning URL.
*
* @param file provisioning file
*/
private void updateConfiguration(final File file)
{
Properties fileProps = new OrderedProperties();
InputStream in = null;
try
{
in = new BufferedInputStream(new FileInputStream(file));
fileProps.load(in);
Iterator<Map.Entry<Object, Object> > it
= fileProps.entrySet().iterator();
while(it.hasNext())
{
Map.Entry<Object, Object> entry = it.next();
String key = (String)entry.getKey();
Object value = entry.getValue();
if(key.equals(PROVISIONING_ALLOW_PREFIX_PROP))
{
String prefixes[] = ((String)value).split("\\|");
/* updates allowed prefixes list */
for(String s : prefixes)
{
allowedPrefixes.add(s);
}
continue;
}
else if(key.equals(PROVISIONING_ENFORCE_PREFIX_PROP))
{
checkEnforcePrefix((String)value);
continue;
}
/* check that properties is allowed */
if(!isPrefixAllowed(key))
{
continue;
}
processProperty(key, value);
}
try
{
/* save and reload the "new" configuration */
ProvisioningActivator.getConfigurationService().
storeConfiguration();
ProvisioningActivator.getConfigurationService().
reloadConfiguration();
}
catch(Exception e)
{
logger.error("Cannot reload configuration");
}
}
catch(IOException e)
{
logger.warn("Error during load of provisioning file");
}
finally
{
try
{
in.close();
file.delete();
}
catch(IOException e)
{
}
}
}
/**
* Check if a property name belongs to the allowed prefixes.
*
* @param key property key name
* @return true if key is allowed, false otherwise
*/
private boolean isPrefixAllowed(String key)
{
if(allowedPrefixes.size() > 0)
{
for(String s : allowedPrefixes)
{
if(key.startsWith(s))
{
return true;
}
}
/* current property prefix is not allowed */
return false;
}
else
{
/* no allowed prefixes configured so key is valid by default */
return true;
}
}
/**
* Process a new property. If value equals "${null}", it means to remove the
* property in the configuration service. If the key name end with
* "PASSWORD", its value is encrypted through credentials storage service,
* otherwise the property is added/updated in the configuration service.
*
* @param key property key name
* @param value property value
*/
private void processProperty(String key, Object value)
{
if((value instanceof String) && ((String)value).equals("${null}"))
{
ProvisioningActivator.getConfigurationService().removeProperty(key);
}
else if(key.endsWith(".PASSWORD"))
{
/* password => credentials storage service */
ProvisioningActivator.getCredentialsStorageService().storePassword(
key.substring(0, key.lastIndexOf(".")),
(String)value);
}
else
{
ProvisioningActivator.getConfigurationService().setProperty(key,
value);
}
}
/**
* Walk through all properties and make sure all properties keys match
* a specific set of prefixes defined in configuration.
*
* @param enforcePrefix list of enforce prefix.
*/
private void checkEnforcePrefix(String enforcePrefix)
{
ConfigurationService config =
ProvisioningActivator.getConfigurationService();
String prefixes[] = null;
if(enforcePrefix == null)
{
return;
}
/* must escape the | character */
prefixes = enforcePrefix.split("\\|");
/* get all properties */
for (String key : config.getAllPropertyNames())
{
boolean isValid = false;
for(String k : prefixes)
{
if(key.startsWith(k))
{
isValid = true;
break;
}
}
/* property name does is not in the enforce prefix list
* so remove it
*/
if(!isValid)
{
config.removeProperty(key);
}
}
}
}

@ -14,6 +14,7 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.netaddr,
net.java.sip.communicator.service.credentialsstorage,
net.java.sip.communicator.service.provisioning,
net.java.sip.communicator.util,
net.java.sip.communicator.util.swing,
javax.swing,
@ -31,3 +32,4 @@ Import-Package: org.osgi.framework,
javax.swing.tree,
javax.swing.undo,
javax.swing.border
Export-Package: net.java.sip.communicator.service.provisioning

@ -607,6 +607,16 @@ private static class HTTPCredentialsProvider
*/
private boolean challengedForCredentials = false;
/**
* Authentication username if any.
*/
private String authUsername = null;
/**
* Authentication password if any.
*/
private String authPassword = null;
/**
* Creates HTTPCredentialsProvider.
* @param usernamePropertyName the property to use to retrieve/store
@ -670,6 +680,9 @@ public Credentials getCredentials(AuthScope authscope)
new String(authWindow.getPassword())
);
authUsername = authWindow.getUserName();
authPassword = new String(authWindow.getPassword());
// if password remember is checked lets save passwords,
// if they seem not correct later will be removed.
if(authWindow.isRememberPassword())
@ -693,6 +706,11 @@ public Credentials getCredentials(AuthScope authscope)
else
{
// we have saved values lets return them
authUsername =
HttpUtilActivator.getConfigurationService().getString(
usernamePropertyName);
authPassword = pass;
return new UsernamePasswordCredentials(
HttpUtilActivator.getConfigurationService().getString(
usernamePropertyName),
@ -721,6 +739,8 @@ public void clear()
passwordPropertyName);
}
this.challengedForCredentials = false;
authUsername = null;
authPassword = null;
}
/**
@ -760,6 +780,24 @@ boolean isChallengedForCredentials()
{
return this.challengedForCredentials;
}
/**
* Returns authentication username if any
* @return authentication username or null
*/
public String getAuthenticationUsername()
{
return authUsername;
}
/**
* Returns authentication password if any
* @return authentication password or null
*/
public String getAuthenticationPassword()
{
return authPassword;
}
}
/**
@ -839,14 +877,14 @@ public static class HTTPResponseResult
/**
* The httpclient.
*/
HttpClient httpClient;
DefaultHttpClient httpClient;
/**
* Creates HTTPResponseResult.
* @param entity the httpclient entity.
* @param httpClient the httpclient.
*/
HTTPResponseResult(HttpEntity entity, HttpClient httpClient)
HTTPResponseResult(HttpEntity entity, DefaultHttpClient httpClient)
{
this.entity = entity;
this.httpClient = httpClient;
@ -900,5 +938,23 @@ public String getContentString()
httpClient.getConnectionManager().shutdown();
}
}
/**
* Get the credentials used by the request.
*/
public String[] getCredentials()
{
String cred[] = new String[2];
if(httpClient != null)
{
HTTPCredentialsProvider prov = (HTTPCredentialsProvider)
httpClient.getCredentialsProvider();
cred[0] = prov.getAuthenticationUsername();
cred[1] = prov.getAuthenticationPassword();
}
return cred;
}
}
}

@ -0,0 +1,52 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.provisioning;
/**
* Provisioning service.
*
* @author Sebastien Vincent
*/
public interface ProvisioningService
{
/**
* Indicates if the provisioning has been enabled.
*
* @return <tt>true</tt> if the provisioning is enabled, <tt>false</tt> -
* otherwise
*/
public String getProvisioningMethod();
/**
* Enables the provisioning with the given method. If the provisioningMethod
* is null disables the provisioning.
*
* @param provisioningMethod the provisioning method
*/
public void setProvisioningMethod(String provisioningMethod);
/**
* Returns provisioning username if any.
*
* @return provisioning username
*/
public String getProvisioningUsername();
/**
* Returns provisioning password if any.
*
* @return provisioning password
*/
public String getProvisioningPassword();
/**
* Returns the provisioning URI.
*
* @return the provisioning URI
*/
public String getProvisioningUri();
}
Loading…
Cancel
Save