aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java
diff options
context:
space:
mode:
authorSebastien Vincent <seb@jitsi.org>2011-12-19 10:08:07 +0000
committerSebastien Vincent <seb@jitsi.org>2011-12-19 10:08:07 +0000
commit2bcf9fe2dedac5eb1f8aa2149fcbcf31d97b25cb (patch)
treeea4a424322830972ca12c18b727c1f50cad9079b /src/net/java
parentb48863e19bcbb5c655389f9a90fe1de5f1da70a1 (diff)
downloadjitsi-2bcf9fe2dedac5eb1f8aa2149fcbcf31d97b25cb.zip
jitsi-2bcf9fe2dedac5eb1f8aa2149fcbcf31d97b25cb.tar.gz
jitsi-2bcf9fe2dedac5eb1f8aa2149fcbcf31d97b25cb.tar.bz2
Refactor provisioning.
Diffstat (limited to 'src/net/java')
-rw-r--r--src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java605
-rw-r--r--src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java57
-rw-r--r--src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java667
-rw-r--r--src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf2
-rw-r--r--src/net/java/sip/communicator/service/httputil/HttpUtils.java60
-rw-r--r--src/net/java/sip/communicator/service/provisioning/ProvisioningService.java52
6 files changed, 836 insertions, 607 deletions
diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java
index 6736fa7..b5aac39 100644
--- a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java
+++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java
@@ -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 @@ import org.osgi.framework.*;
*/
public class ProvisioningActivator
implements BundleActivator
-{
+{
/**
* Logger of this class
*/
@@ -46,54 +39,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 class ProvisioningActivator
2000, true),
properties);
- String method = getProvisioningMethod();
+ String method = provisioningService.getProvisioningMethod();
if(method == null || method.equals("NONE"))
{
@@ -193,28 +130,11 @@ public class ProvisioningActivator
}
}
}
-
- 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]");
@@ -235,73 +155,6 @@ public class ProvisioningActivator
}
/**
- * 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.
*
* @return the <tt>UIService</tt> obtained from the bundle context
@@ -345,426 +198,6 @@ public class ProvisioningActivator
}
/**
- * 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
* found.
@@ -827,4 +260,14 @@ public class ProvisioningActivator
}
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;
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java
index 50cc9f2..151a119 100644
--- a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java
+++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java
@@ -169,7 +169,8 @@ public class 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 class ProvisioningForm
*/
private void initButtonStates()
{
- String provMethod = ProvisioningActivator.getProvisioningMethod();
+ String provMethod = ProvisioningActivator.getProvisioningService().
+ getProvisioningMethod();
boolean isProvEnabled
= (provMethod != null
&& provMethod.length() > 0
@@ -296,7 +298,8 @@ public class ProvisioningForm
{
manualButton.setSelected(true);
- String uri = ProvisioningActivator.getProvisioningUri();
+ String uri = ProvisioningActivator.getProvisioningService().
+ getProvisioningUri();
if (uri != null)
uriField.setText(uri);
}
@@ -311,16 +314,16 @@ public class ProvisioningForm
// 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 @@ public class ProvisioningForm
}
}
- ProvisioningActivator
- .setProvisioningMethod(provisioningMethod);
+ ProvisioningActivator.getProvisioningService().
+ setProvisioningMethod(provisioningMethod);
}
});
@@ -377,8 +380,8 @@ public class ProvisioningForm
public void stateChanged(ChangeEvent e)
{
if (dhcpButton.isSelected())
- ProvisioningActivator
- .setProvisioningMethod("DHCP");
+ ProvisioningActivator.getProvisioningService().
+ setProvisioningMethod("DHCP");
}
});
@@ -387,8 +390,8 @@ public class ProvisioningForm
public void stateChanged(ChangeEvent e)
{
if (dnsButton.isSelected())
- ProvisioningActivator
- .setProvisioningMethod("DNS");
+ ProvisioningActivator.getProvisioningService().
+ setProvisioningMethod("DNS");
}
});
@@ -397,8 +400,8 @@ public class ProvisioningForm
public void stateChanged(ChangeEvent e)
{
if (bonjourButton.isSelected())
- ProvisioningActivator
- .setProvisioningMethod("Bonjour");
+ ProvisioningActivator.getProvisioningService().
+ setProvisioningMethod("Bonjour");
}
});
@@ -412,15 +415,19 @@ public class ProvisioningForm
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 class ProvisioningForm
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 class ProvisioningForm
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 class ProvisioningForm
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("");
diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java
new file mode 100644
index 0000000..58d2e57
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java
@@ -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);
+ }
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf b/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf
index 7f8503a..ea2d941 100644
--- a/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf
@@ -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
diff --git a/src/net/java/sip/communicator/service/httputil/HttpUtils.java b/src/net/java/sip/communicator/service/httputil/HttpUtils.java
index f72b4b2..bc3f839 100644
--- a/src/net/java/sip/communicator/service/httputil/HttpUtils.java
+++ b/src/net/java/sip/communicator/service/httputil/HttpUtils.java
@@ -608,6 +608,16 @@ public class HttpUtils
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
* username value if protected site is hit, for username
@@ -670,6 +680,9 @@ public class HttpUtils
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 class HttpUtils
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 class HttpUtils
passwordPropertyName);
}
this.challengedForCredentials = false;
+ authUsername = null;
+ authPassword = null;
}
/**
@@ -760,6 +780,24 @@ public class HttpUtils
{
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 class HttpUtils
/**
* 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 class HttpUtils
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;
+ }
}
}
diff --git a/src/net/java/sip/communicator/service/provisioning/ProvisioningService.java b/src/net/java/sip/communicator/service/provisioning/ProvisioningService.java
new file mode 100644
index 0000000..5887bdb
--- /dev/null
+++ b/src/net/java/sip/communicator/service/provisioning/ProvisioningService.java
@@ -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();
+}