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(); + } + } }