Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
ProxySupport
This page is being used to capture the requirements for Platform level proxy support (bug 154100)
Contents
CVS Requirements
The CVS/Core and CVS/SSH2 use the proxies provided by the Jsch plug-in to make proxy connections. Currently, there is support for two types of proxies: HTTP and SOCKS5. We would require API that allowed us to do something like this:
ProxyInfo[] infos = ProxyInfo.getProxiesFor(String hostName); ProxyInfo info = getSupportProxy(infos); // method would look for the HTTP or SOCKS5 proxy if (info == null) { // Attempt a direct connection. // If the connection failed and there were proxies specified, let the user know that // we only support HTTP and SOCKS4 } else if (info.getType() == ProxyInfo.HTTP) { // Use host, port, username and password to create an HTTP proxy using Jsch } else if (info.getType() == Proxy.SOCKS5) { // Use host, port, username and password to create a SOCKS5 proxy using Jsch }
The API we would require is that ability to retrieve the set of proxies that are available for a particular host. This doesn't imply that we need to support the specification of different proxies for each hist but I think it is good to leave room in the API to support this later.
Update Requirements
Update allows the user to enable an HTTP proxy and specify an address and port that is to be used as the proxy. When set, this information is places in the 'http.proxySet', 'http.proxyHost' and 'http.proxyPort' system properties. Update also sets the default authenticator (Athenticator.setDefault(...)) in order to support interactive authentication (i.e the user is prompted if the update server or proxy require authentication).
WTP Requirements
The WTP proxy preference page currently only sets JVM system properties for http, https, and socks. It does not provide any api to access this information. It assumes that clients will use Java IO( which uses these properties) to create connections. Since, a number of components in WTP use Java IO to open connections, these JVM system properties need to set when the Eclipse UI starts up. This preference page also sets the default authenticator at UI startup time so that the user is prompted for userid and password information. The authenticator also caches user id and password information so that if the same host is accessed again the user does not need to enter this information again.
Discussion
Here are discussions on various aspects of this feature
Access to Proxy info
For CVS to use this feature, the Core plug-in needs to provide access to the defined proxy settings. It also needs the authentication information, if there is any, to be provided with the proxy information since the Jsch proxy does not appear to support an authentication callback. From a CVS standpoint, we need API that looks something like this:
- a proxy info (or data) object that contains the type, hist, port, username (if required) and password (if required).
- a method to retrieve the proxy info (or infos) for a particular target host. Clients will need to pick an appropriate proxy to use.
To support this, we would need a preference page that allows the specification of multiple proxy types along with the authentication for each type, if there is any.
Setting System Properties
Both Update and WTP set the Java proxy system properties. For Update, this is done when the core bundle starts. However, WTP does this using the startup hook to ensure that the properties are set when any URL or TCP (in Java 1.5) connections are attempted. In the current implementation, it seems that WTP and Update could easily interfer with each other.
One approach to this is to have the new plug-ins just set these properties for everyone. This is fairly critical as these system properties are a standard aspect of the JDK, apply to the entire JVM, and should be aligned to Eclipse's Internet configuration settings as early as possible. The advantage of this is that clients of URL and 1.4 and URL and TCP in 1.5 would get the proxy support automatically. However, the main issue is that the settings would need to be put in the properties before any connections were attempted. Possible approaches to solve this would be:
- specify the options on the command line (not really an option but we do need to consider what happens if somebody does provide them this way)
- don't specify Lazy-start in the bundle manifest (I'm not sure about this but I'll find out)
- use the Workbench IStartup hook, although being a UI extension point this would presumably not pan out for headless Eclipse applications.
- require any clients that want proxy support to depend on the Core proxy plug-in and call a method indicating that they require the properties to be set.
It seems a bit wierd to force every client the uses Java I/O to have to also make call to the Proxy plug-in to enable JVM properties. However, bundles in the Platform are not typically loaded during startup except extension points or dependencies. It may be difficult to get approval to have the proxy bundle start automatically so we may have to settle for point 4, at least for 3.3.
That said, the central purpose of this enhancement is to correct the ambiguous and often conflicting behaviour resulting from plugins colliding on the JVM's single network configuration. In the interest of performance, startup activities must be kept to a necessary minimum, however, establishing control over "static" JVM properties is the sort of activity that is appropriate and necessary as early in the startup cycle as reasonably possible.
[YMNK]I have questions about setting System Property "socksProxyHost"
- If "socksProxyHost" is enabled, will "http.proxyHost" and "https.proxyHost" be ignored?
- It seems there is not a property like "socksNonProxyHosts".
Will TCP connections to "localhost" be also proxied? From a CVS standpoint, to support "pserverssh2", it will use ssh2's local port-forwarding and it requires direct accesses to "localhost".
[CB] See [Java Networking and Proxies] and [Networking Properties]. First, HTTP proxy settings take precedence over SOCKS. Second, so far, I haven't found the moral equivalent of nonProxyHosts for SOCKS.
Authenticator
One of the JVM settings that Update and WTP set is the Authenticator. The authenticator is invoked by some Java I/O classes when a username and password is required when making a connection. The Update authenticator simply prompts for the username and password while the WTP authenticator caches authentication iformation.
It would appear that the Java Authenticator API does not provide the ability to differentiate between a prompt caused by a lack of credentials vs. a prompt caused by a failed authentication. Because of this, it is difficult to cache credentials either through a preference page or by remembering what was returned when the Authenticator was invoked. WTP does cache in their authenticator and in the situation where the credentials have changed or the user enter incorrect credential information Eclipse would need to be restarted to flush this cached data. This is not behavior we are willing to put in the Platform.
Because of this, we have the following conflict between the requirements of CVS/SSH2 and Update/WTP.
- WTP and Update depend on the use of the java.net.Authenticator which doesn't really support pre-specification or caching of passwords (i.e. it is better to prompt more often then it is to force the user to restart if they enter the wrong password).
[PM]Given the issues with regard to caching credentials, we (WTP) could live without this functionality. The important issue for WTP is that some form of Authenticator be present. If the Authenticator that Update uses was put into the new Eclipse internet plugin I'm sure that this would be fine.
[CB] I agree WTP can live without caching, at least in the short term. The requirement that some form of Authenticator be present in the Eclipse platform is important to a few Eclipse components. As with proxy settings, a single reasonable Authenticator, such as Update's, or WTP's minus caching, is essential to lock consistent reliable behaviour into the extensible platform.
- CVS (and SSH2) depend on the JSch proxy classes which need the user name and password up front (i.e JSch proxy support works with Java 1.4).
[PM] WTP also requires username and password specified up front for proxies, so there shouldn't be a conflict here.
What this means is that we need a preference page that includes the username and password (at least for http and socks) so that CVS and SSH2 proxy support can be used. The user would then expect these passwords to be used when using the Java proxy support as well. I guess we could solve this with an Authenticator that used the provided user name and password for the proxies and prompted for other connections. This would give a unified experience across WTP, CVS, SSH2 and Update but would have the failing that, if proxy authentication failed, the user would not be prompted to authenticate but instead would have to somehow know to go to the preference page and reenter the authentication information (although one assumes that they entered it in the first place so it may be acceptable).
[CB/PM] http.proxyUser and http.proxyPassword are consulted for tunneling thru a proxy before the Authenticator gets involved, which means we can keep the Authenticator out of the proxy conflict equation between jsch and java.net, and use the Authenticator chiefly for providing credentials for the actual http/https service endpoints.
The above described solution is not ideal but may be the best we can do given the limitations of the two proxy APIs we are using. However, any time prompt backs are involved, I consider the feature to be non-trivial (i.e. there always seem to be unforeseen problems that occur). Given that we are late in the cycle, I would be more comfortable with a solution that did not involve the Platform providing the Authenticator in 3.3. Hence my proposal was for an API that addressed the multiple preference page issue with the least amount of risk and while it doesn't make things much better for clients, doesn't make it any worse than it already is. Once 3.3 ships, we could get an early start on get the Authenticator story right.
Anyway, anything we do for this feature in 3.3 requires PMC approval. I will seek their input on the following possibilities (if you think I missed a possible solution, let me know):
- The Platform provides only the preference page settings and it is up to clients to set the JVM properties and the authenticator as they do today.
- The Platform provides the preference page and settings and a means for clients to indicate that that the Authenticator should be set and the JVM properties should be set and kept up-to-date. The Authenticator would just prompt when a password is required (as the Update Authenticator does).
- Same as 2 but the Authenticator uses the user name and password from the preference page when proxy connections are attempted.
[PM] Option 2 would be fine for WTP.
[CB] Technically, option 1 is possible, however, consistent internet connection behaviour means the ability to connect to open or basic-auth service endpoints possibly via open or basic-auth proxies. Provision for Proxy settings and Basic Auth credentials are joined at the hip. Addressing one but not the other leaves 154100 incomplete. The damage from different plugins stepping on each other's Authenticators isn't much more palatable than allowing plugins to step on each other's proxy settings. Again, I'm not suggesting a fancy Authenticator here, but we need something simple to bring an end to the java.net free-for-all.
Another issue with the Authenticator is that it must be registered at startup and must be provided by a UI plug-in. Either we would need to designate the UI plug-in as early startup or we would need API at the UI level that clients would need to call to indicate that they desire to have an Authenticator registered.
[CB] Eventually (after 3.3) when we have more time to write a better Authenticator that does cache, this issue will go away since a UI plugin will not need to be activated, and nor should it, since headless Eclipse apps should also have the ability to connect to basic auth protected resources and could do so by consulting persisted credentials. Meanwhile, since we only have a UI expression of the Authenticator for now, the IStartup extension could suffice here. As commented on above, the earlier this is done the more completely we fix the inconsistent behaviour troubling the platform today. If absolutely necessary WTP plugins could explicitly drive initialization of JVM system properties and the Authenticator, but only slightly improves on the problems described in the RFE.
Preference Page
Another issue to consider is the design of the preference page for modifying proxy settings. Here are some questions I have about what is in the latest patch:
- There is a single field for non-proxied hosts but each protocol (i.e. http and https) in the Core plug-in has its own preference for this (expect for socks which may be a problem for CVS as indicated by the question by YMNK above). It does not appear that the single list is used by the Core plug-in. Will a single list be adequate or do we need to have separate lists for each protocol? I would assume that we only need a single list but I would like confirmation on this.
[PM]I agree that having a non proxy list for each protocol would be nice to have, but I don't think we have the time to implement this in the first release. The core plugin has been implemented so that it can handle a separate non proxy hosts list for each protocol. However, the UI only allows the user to specify one non proxy host list. This list is passed to all three protocols registered in the core. From a WTP perspective I think this should be adequate. With regards to YMNK's question, if both protocols are set the client would have the choice of which one to use. The code list at the beginning of this document does this. It has a preference towards the http protocol which should be fine. - There are other fields in the preference page (use same protocol, user name and password) that do not appear to be pushed down into the Core settings. My assumption is that the preference page was put in the patch as a proof of concept for those fields without actually hooking them up. Please let me know if I am mistaken.
[PM] I intended the "use same protocol" check box to be just a UI short cut so that the user would not have to specify this information many times. Therefore, the state of this check box is not passed to the core plugin. However, the user id and password should be passed to the core plugins. If it isn't then this is bug. - From the Core level data structures, it would appear that each protocol requires it's own authentication information but the current layout of the preference page does not support this. Perhaps we need a separate tab (or preference page) for each proxy type. I understand that the desire was to look like Firefox but I think Firefox can get away with this because they have a cleaner prompting story.
[PM]I agree that it would be preferable to have user id and password specifiable per protocol. If you think that we can do a design and implemenation of this in a week or so then lets go for it. However, the practical side of me says that we should stick to the bare minimum and leave this to the next release. - One things Firefox does have is a toggle to differentiate Socks4 from Socks5. This may be useful to have from a CVS standpoint since the two proxy types are different in JSch. Can anyone comment on whether Socks4 is used often. If not, we probably don't need to differentiate (I should note that the java.net Socks proxy support covers both Socks4 and Socks5 so this is only an issue of JSch).
[PM] My understanding of SOCKS4 and SOCKS5 is that SOCKS4 does not have authentication, but SOCKS5 does. Therefore, a client getting the ProxyData could differentiate which one to use based on whether a user id and password were specified or not. If this data was specified SOCKS5 would be used if not SOCKS4 would be used. Therefore, I don't think we need to ask the user for this information. I think in the initial release of this code we should leave this out and if it becomes a problem in the future then add it later.
[YMNK] I agree with [PM]. We should leave this out in the initial release. The following is just a FYI. Unfortunately, SOCKS4 and SOCKS5 is not compatible and clients must know if the socks server is SOCKS4 or SOCKS5 before starting the connection. This is the reason that Firefox has a toggle for them. I don't know the internal implementation of java.net,but it will guess by the huristics as you have written above. Every SOCKS5 server, however, must not run with the password protection and java.net may fail and try the reconnection. IMHO, it is not so smart and there should be a toggle for socks version on the preference-page in the future. - I also noticed that Firefox does not differentiate HTTP and HTTPS proxy types but the patch does. In practice, do clients ever have both types of proxies or is this separation done in the patch simply because there are two different sets of properties in the JVM. Do we need to have both the HTTP and HTTPS fields (or is the HTTPS proxy in the patch equivalent to the SSL proxy in Firefox)?
[PM]My understanding is that the HTTPS proxy ( which is HTTP over SSL ) should be equivalent to the SSL proxy in Firefox. Please, correct me if I'm wrong here. As well, the JVM has separate system properties for HTTP and HTTPS so I think the user should be able to specify them separately. In the current WTP internet preference page we set both the HTTP and HTTPS settings to the same values and have gotten some complaints about this behavior.
[YMNK] You are right. HTTPS corresponds to SSL proxy on the Firefox.