diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties
index 0c94c8f97..f5bda711c 100644
--- a/lib/felix.client.run.properties
+++ b/lib/felix.client.run.properties
@@ -54,7 +54,8 @@ felix.auto.start.49= \
reference:file:sc-bundles/bouncycastle.jar \
reference:file:sc-bundles/zrtp4j.jar \
reference:file:sc-bundles/protocol.jar \
- reference:file:lib/bundle/httpcore.jar
+ reference:file:lib/bundle/httpcore.jar \
+ reference:file:sc-bundles/globalproxyconfig.jar
#the contact list service depends on protocol.jar
#some protocol implementations however depend on the contact list
@@ -128,8 +129,7 @@ felix.auto.start.67= \
reference:file:sc-bundles/generalconfig.jar \
reference:file:sc-bundles/dictaccregwizz.jar \
reference:file:sc-bundles/otr.jar \
- reference:file:sc-bundles/facebookaccregwizz.jar \
- reference:file:sc-bundles/globalproxyconfig.jar
+ reference:file:sc-bundles/facebookaccregwizz.jar
#level 68 is for profiler, don't use it or change the build.xml file accordingly
diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index 962112ef9..8df37a428 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -876,5 +876,12 @@ plugin.globalproxy.PROXY_USERNAME=Proxy username
plugin.globalproxy.PROXY_PASSWORD=Proxy password
plugin.globalproxy.DESCRIPTION={0} will use the above proxy \
settings for all networks you connect or reconnect to from now on. \n\
-Proxy support is currently experimental and only works with some protocols like \
-Jabber, AIM, and ICQ. Others will follow.
+Proxy support is currently experimental and only works with some protocols. \
+Check out the table below for more details:
+plugin.globalproxy.PROTOCOL_SUPPORT=
\
+ | SOSCKS4/5 | SOSCKS4/5+Auth | HTTP | HTTP+Auth |
\
+| Yahoo! | + | + | - | - |
\
+| MSN | + | + | - | - |
\
+| JABBER | + | + | + | + |
\
+| ICQ/AIM | + | + | + | + |
\
+
diff --git a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
index fa807537c..afb164734 100644
--- a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
@@ -314,7 +314,7 @@ private void connectAndLogin(SecurityAuthority authority, int reasonCode)
IcqActivator.getConfigurationService()
.getString(ProxyInfo.CONNECTON_PROXY_TYPE_PROPERTY_NAME);
if(globalProxyType != null &&
- !globalProxyType.equals(ProxyInfo.ProxyType.NONE.name()))
+ globalProxyType.equals(ProxyInfo.ProxyType.HTTP.name()))
{
String globalProxyAddress =
IcqActivator.getConfigurationService().getString(
@@ -348,44 +348,19 @@ private void connectAndLogin(SecurityAuthority authority, int reasonCode)
OperationFailedException.INVALID_ACCOUNT_PROPERTIES);
}
- if(globalProxyType.equals(ProxyInfo.ProxyType.HTTP.name()))
- {
- // If we are using http proxy, sometimes
- // default port 5190 is forbidden, so force
- // http/https port
- AimConnectionProperties connProps =
- new AimConnectionProperties(
- new Screenname(getAccountID().getUserID())
- , password);
- connProps.setLoginHost("login.icq.com");
- connProps.setLoginPort(443);
- aimConnection = aimSession.openConnection(connProps);
- aimConnection.setProxy(AimProxyInfo.forHttp(
- globalProxyAddress, proxyPort,
- globalProxyUsername, globalProxyPassword));
- }
- else
- {
- aimConnection = aimSession.openConnection(
- new AimConnectionProperties(
- new Screenname(getAccountID().getUserID())
- , password));
-
- if(globalProxyType.equals(
- ProxyInfo.ProxyType.SOCKS4.name()))
- {
- aimConnection.setProxy(AimProxyInfo.forSocks4(
- globalProxyAddress, proxyPort,
- globalProxyUsername));
- }
- else if(globalProxyType.equals(
- ProxyInfo.ProxyType.SOCKS5.name()))
- {
- aimConnection.setProxy(AimProxyInfo.forSocks5(
- globalProxyAddress, proxyPort,
- globalProxyUsername, globalProxyPassword));
- }
- }
+ // If we are using http proxy, sometimes
+ // default port 5190 is forbidden, so force
+ // http/https port
+ AimConnectionProperties connProps =
+ new AimConnectionProperties(
+ new Screenname(getAccountID().getUserID())
+ , password);
+ connProps.setLoginHost("login.icq.com");
+ connProps.setLoginPort(443);
+ aimConnection = aimSession.openConnection(connProps);
+ aimConnection.setProxy(AimProxyInfo.forHttp(
+ globalProxyAddress, proxyPort,
+ globalProxyUsername, globalProxyPassword));
}
else
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
index 437afd8a3..30e60829a 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java
@@ -670,62 +670,12 @@ public void fireProviderStatusChangeEvent(
currentStatus = newStatus;
super.fireProviderStatusChangeEvent(oldStatus, newStatus);
- }
- }
-
- /**
- * Our listener that will tell us when we're registered to server
- * and is ready to accept us as a listener.
- */
- private class RegistrationStateListener
- implements RegistrationStateChangeListener
- {
- /**
- * The method is called by a ProtocolProvider implementation whenver
- * a change in the registration state of the corresponding provider had
- * occurred.
- * @param evt ProviderStatusChangeEvent the event describing the status
- * change.
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- logger.debug("The Jabber provider changed state from: "
- + evt.getOldState()
- + " to: " + evt.getNewState());
-
- if(evt.getNewState() == RegistrationState.REGISTERED)
- {
- contactChangesListener = new ContactChangesListener();
- parentProvider.getConnection().getRoster()
- .addRosterListener(contactChangesListener);
- fireProviderStatusChangeEvent(
- currentStatus,
- parentProvider
- .getJabberStatusEnum()
- .getStatus(JabberStatusEnum.AVAILABLE));
-
- // init ssList
- ssContactList.init();
- }
- else if(evt.getNewState() == RegistrationState.UNREGISTERED
- || evt.getNewState() == RegistrationState.AUTHENTICATION_FAILED
- || evt.getNewState() == RegistrationState.CONNECTION_FAILED)
- {
- //since we are disconnected, we won't receive any further status
- //updates so we need to change by ourselves our own status as
- //well as set to offline all contacts in our contact list that
- //were online
- PresenceStatus oldStatus = currentStatus;
- PresenceStatus offlineStatus =
+ PresenceStatus offlineStatus =
parentProvider.getJabberStatusEnum().getStatus(
JabberStatusEnum.OFFLINE);
- currentStatus = offlineStatus;
-
- fireProviderStatusChangeEvent(oldStatus, currentStatus);
-
- contactChangesListener = null;
-
+ if(newStatus.equals(offlineStatus))
+ {
//send event notifications saying that all our buddies are
//offline. The protocol does not implement top level buddies
//nor subgroups for top level groups so a simple nested loop
@@ -780,7 +730,62 @@ else if(evt.getNewState() == RegistrationState.UNREGISTERED
, contact.getParentContactGroup()
, oldContactStatus, offlineStatus);
}
+ }
+ }
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to server
+ * and is ready to accept us as a listener.
+ */
+ private class RegistrationStateListener
+ implements RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever
+ * a change in the registration state of the corresponding provider had
+ * occurred.
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ logger.debug("The Jabber provider changed state from: "
+ + evt.getOldState()
+ + " to: " + evt.getNewState());
+
+ if(evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ contactChangesListener = new ContactChangesListener();
+ parentProvider.getConnection().getRoster()
+ .addRosterListener(contactChangesListener);
+ fireProviderStatusChangeEvent(
+ currentStatus,
+ parentProvider
+ .getJabberStatusEnum()
+ .getStatus(JabberStatusEnum.AVAILABLE));
+
+ // init ssList
+ ssContactList.init();
+ }
+ else if(evt.getNewState() == RegistrationState.UNREGISTERED
+ || evt.getNewState() == RegistrationState.AUTHENTICATION_FAILED
+ || evt.getNewState() == RegistrationState.CONNECTION_FAILED)
+ {
+ //since we are disconnected, we won't receive any further status
+ //updates so we need to change by ourselves our own status as
+ //well as set to offline all contacts in our contact list that
+ //were online
+ PresenceStatus oldStatus = currentStatus;
+ PresenceStatus offlineStatus =
+ parentProvider.getJabberStatusEnum().getStatus(
+ JabberStatusEnum.OFFLINE);
+ currentStatus = offlineStatus;
+
+ fireProviderStatusChangeEvent(oldStatus, currentStatus);
+
+ contactChangesListener = null;
}
}
}
diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java
index bb55c0326..9f60ecf21 100644
--- a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java
+++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java
@@ -21,7 +21,8 @@
*/
public class GlobalProxyConfigForm
extends TransparentPanel
- implements ActionListener
+ implements ActionListener,
+ KeyListener
{
/**
* Hold the available proxy types.
@@ -64,6 +65,11 @@ public GlobalProxyConfigForm()
*/
private void init()
{
+ serverAddressField.addKeyListener(this);
+ portField.addKeyListener(this);
+ usernameField.addKeyListener(this);
+ passwordField.addKeyListener(this);
+
this.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
TransparentPanel centerPanel = new TransparentPanel(new GridBagLayout());
@@ -125,7 +131,7 @@ private void init()
constraints.gridy = 4;
constraints.gridwidth = 4;
constraints.gridheight = 2;
- constraints.insets = new Insets(20,20,20,20);
+ constraints.insets = new Insets(20,15,20,15);
JTextPane pane = new JTextPane();
pane.setEditable(false);
pane.setOpaque(false);
@@ -137,21 +143,22 @@ private void init()
pane,
constraints);
- add(centerPanel, BorderLayout.NORTH);
-
- TransparentPanel p = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
- JButton saveButton = new JButton(
- Resources.getString("service.gui.SAVE"));
- saveButton.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e)
- {
- saveValues();
- }
- });
- p.add(saveButton);
+ constraints.gridx = 0;
+ constraints.gridy = 6;
+ constraints.gridwidth = 4;
+ constraints.gridheight = 2;
+ constraints.insets = new Insets(20,20,20,20);
+ JEditorPane table = new JEditorPane();
+ table.setContentType("text/html");
+ table.setEditable(false);
+ table.setOpaque(false);
+ table.setText(Resources.getString(
+ "plugin.globalproxy.PROTOCOL_SUPPORT"));
+ centerPanel.add(
+ table,
+ constraints);
- add(p, BorderLayout.SOUTH);
+ add(centerPanel, BorderLayout.NORTH);
}
/**
@@ -162,17 +169,6 @@ private void loadValues()
ConfigurationService configService =
GlobalProxyPluginActivator.getConfigurationService();
- try
- {
- String type = configService.getString(
- ProxyInfo.CONNECTON_PROXY_TYPE_PROPERTY_NAME);
- if(type != null)
- typeCombo.setSelectedItem(ProxyInfo.ProxyType.valueOf(type));
- } catch (IllegalArgumentException e)
- {
- // wrong proxy type stored in configuration
- }
-
String serverAddress = configService.getString(
ProxyInfo.CONNECTON_PROXY_ADDRESS_PROPERTY_NAME);
if(serverAddress != null)
@@ -189,10 +185,24 @@ private void loadValues()
usernameField.setText(username);
String password = configService.getString(
- ProxyInfo.CONNECTON_PROXY_USERNAME_PROPERTY_NAME);
+ ProxyInfo.CONNECTON_PROXY_PASSWORD_PROPERTY_NAME);
if(password != null)
passwordField.setText(password);
+ // we load the types at the end cause a event will ne trigered
+ // when selecting the configured value, which will eventually
+ // trigger a save operation
+ try
+ {
+ String type = configService.getString(
+ ProxyInfo.CONNECTON_PROXY_TYPE_PROPERTY_NAME);
+ if(type != null)
+ typeCombo.setSelectedItem(ProxyInfo.ProxyType.valueOf(type));
+ } catch (IllegalArgumentException e)
+ {
+ // wrong proxy type stored in configuration
+ }
+
if(typeCombo.getSelectedItem().equals(ProxyInfo.ProxyType.NONE))
{
serverAddressField.setEnabled(false);
@@ -245,14 +255,30 @@ private void saveValues()
String username = usernameField.getText();
if(username != null && username.length() > 0)
+ {
configService.setProperty(
ProxyInfo.CONNECTON_PROXY_USERNAME_PROPERTY_NAME, username);
+ }
+ else
+ {
+ configService.removeProperty(
+ ProxyInfo.CONNECTON_PROXY_USERNAME_PROPERTY_NAME);
+ }
char[] password = passwordField.getPassword();
if(password.length > 0)
+ {
configService.setProperty(
ProxyInfo.CONNECTON_PROXY_PASSWORD_PROPERTY_NAME,
new String(password));
+ }
+ else
+ {
+ configService.removeProperty(
+ ProxyInfo.CONNECTON_PROXY_PASSWORD_PROPERTY_NAME);
+ }
+
+ GlobalProxyPluginActivator.initProperties();
}
/**
@@ -275,5 +301,30 @@ public void actionPerformed(ActionEvent e)
usernameField.setEnabled(true);
passwordField.setEnabled(true);
}
+
+ saveValues();
+ }
+
+ /**
+ * Not used.
+ * @param e
+ */
+ public void keyTyped(KeyEvent e)
+ {}
+
+ /**
+ * Not used.
+ * @param e
+ */
+ public void keyPressed(KeyEvent e)
+ {}
+
+ /**
+ * Used to listen for changes and saving on every change.
+ * @param e
+ */
+ public void keyReleased(KeyEvent e)
+ {
+ saveValues();
}
}
diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
index 5767a01ce..36702056d 100644
--- a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
+++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java
@@ -6,8 +6,10 @@
*/
package net.java.sip.communicator.plugin.globalproxyconfig;
+import java.net.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import org.osgi.framework.*;
@@ -56,6 +58,8 @@ public void start(BundleContext bc) throws Exception
51),
null);
+ initProperties();
+
logger.info("GLOBAL PROXY CONFIGURATION PLUGIN... [REGISTERED]");
}
@@ -87,4 +91,162 @@ public static ConfigurationService getConfigurationService()
return configService;
}
+
+ /**
+ * Init system properties that corresponds to proxy settings.
+ */
+ static void initProperties()
+ {
+ // Activate proxy settings
+ String globalProxyType = getConfigurationService()
+ .getString(ProxyInfo.CONNECTON_PROXY_TYPE_PROPERTY_NAME);
+ if(globalProxyType != null &&
+ !globalProxyType.equals(ProxyInfo.ProxyType.NONE.name()))
+ {
+ String globalProxyAddress =
+ getConfigurationService().getString(
+ ProxyInfo.CONNECTON_PROXY_ADDRESS_PROPERTY_NAME);
+ String globalProxyPortStr =
+ getConfigurationService().getString(
+ ProxyInfo.CONNECTON_PROXY_PORT_PROPERTY_NAME);
+ int globalProxyPort = -1;
+ try
+ {
+ globalProxyPort = Integer.parseInt(
+ globalProxyPortStr);
+ }
+ catch(NumberFormatException ex)
+ {
+ // problem parsing port, will not set it
+ }
+ String globalProxyUsername =
+ getConfigurationService().getString(
+ ProxyInfo.CONNECTON_PROXY_USERNAME_PROPERTY_NAME);
+ String globalProxyPassword =
+ getConfigurationService().getString(
+ ProxyInfo.CONNECTON_PROXY_PASSWORD_PROPERTY_NAME);
+ if(globalProxyAddress == null ||
+ globalProxyAddress.length() <= 0)
+ {
+ // no address
+ return;
+ }
+
+ String type = null;
+ if(globalProxyType.equals(
+ ProxyInfo.ProxyType.HTTP.name()))
+ {
+ type = "HTTP";
+
+ // java network properties
+ System.setProperty(
+ "http.proxyHost", globalProxyAddress);
+
+ if(globalProxyPortStr != null)
+ {
+ System.setProperty(
+ "http.proxyPort", globalProxyPortStr);
+ }
+
+ // used by some protocols like yahoo
+ System.setProperty(
+ "proxySet", "true");
+ }
+ else if(globalProxyType.equals(
+ ProxyInfo.ProxyType.SOCKS4.name()) ||
+ globalProxyType.equals(
+ ProxyInfo.ProxyType.SOCKS5.name()))
+ {
+ type = "SOCKS";
+
+ // java network properties
+ System.setProperty(
+ "socksProxyHost", globalProxyAddress);
+
+ if(globalProxyPortStr != null)
+ {
+ System.setProperty(
+ "socksProxyPort", globalProxyPortStr);
+ }
+
+ // used by some protocols like yahoo
+ System.setProperty(
+ "socksProxySet", "true");
+ }
+
+ Authenticator.setDefault(new AuthenticatorImpl(
+ globalProxyAddress, globalProxyPort,
+ type,
+ globalProxyUsername, globalProxyPassword));
+ }
+ else
+ Authenticator.setDefault(null);
+ }
+
+ /**
+ * Gets care of the proxy configurations which require authentication.
+ */
+ private static class AuthenticatorImpl
+ extends Authenticator
+ {
+
+ /**
+ * The proxy port we are serving.
+ */
+ String host;
+ /**
+ * The port that is used.
+ */
+ int port;
+ /**
+ * Type of the proxy config.
+ */
+ String type;
+ /**
+ * The username to supply.
+ */
+ String username;
+ /**
+ * The password to supply.
+ */
+ String password;
+
+ /**
+ * Creates it.
+ * @param host The proxy port we are serving.
+ * @param port The port that is used.
+ * @param type Type of the proxy config.
+ * @param username The username to supply.
+ * @param password The password to supply.
+ */
+ public AuthenticatorImpl(String host, int port,
+ String type, String username, String password)
+ {
+ this.host = host;
+ this.port = port;
+ this.type = type;
+ this.username = username;
+ this.password = password;
+ }
+
+ /**
+ * Called when password authorization is needed. Subclasses should
+ * override the default implementation, which returns null.
+ * @return The PasswordAuthentication collected from the
+ * user, or null if none is provided.
+ */
+ protected PasswordAuthentication getPasswordAuthentication()
+ {
+ if(getRequestingProtocol().startsWith(type)
+ && getRequestingHost().equals(host)
+ && port == getRequestingPort()
+ && getRequestorType().equals(Authenticator.RequestorType.SERVER))
+ {
+ return new PasswordAuthentication(
+ username, password.toCharArray());
+ }
+ else
+ return super.getPasswordAuthentication();
+ }
+ }
}