View Javadoc

1   /*
2    * Copyright 2009 University Corporation for Advanced Internet Development, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package edu.internet2.middleware.shibboleth.common.resource;
18  
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import javax.net.ssl.TrustManager;
25  
26  import net.jcip.annotations.ThreadSafe;
27  
28  import org.opensaml.xml.util.DatatypeHelper;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  import org.tmatesoft.svn.core.SVNErrorMessage;
32  import org.tmatesoft.svn.core.SVNException;
33  import org.tmatesoft.svn.core.SVNURL;
34  import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
35  import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
36  import org.tmatesoft.svn.core.auth.ISVNProxyManager;
37  import org.tmatesoft.svn.core.auth.SVNAuthentication;
38  import org.tmatesoft.svn.core.io.SVNRepository;
39  
40  /** Authentication manager for SVN resources. */
41  @ThreadSafe
42  public class SVNBasicAuthenticationManager implements ISVNAuthenticationManager {
43  
44      /** Class logger. */
45      private final Logger log = LoggerFactory.getLogger(SVNBasicAuthenticationManager.class);
46  
47      /** Network connection timeout in milliseconds. */
48      private int connectionTimeout;
49  
50      /** Read operation timeout in milliseconds. */
51      private int readTimeout;
52  
53      private TrustManager trustManager;
54  
55      /** User authentication mechanisms. */
56      private Map<String, SVNAuthentication> authenticationMethods;
57  
58      /** HTTP proxy configuration. */
59      private final BasicProxyManager proxyManager;
60  
61      /**
62       * Constructor.
63       * 
64       * @param authnMethods user authentication methods
65       */
66      public SVNBasicAuthenticationManager(List<SVNAuthentication> authnMethods) {
67          connectionTimeout = 5000;
68          readTimeout = 10000;
69          setAuthenticationMethods(authnMethods);
70          proxyManager = null;
71      }
72  
73      /**
74       * Constructor.
75       * 
76       * @param authnMethods user authentication methods
77       * @param proxyHost host name or IP address of the proxy server
78       * @param proxyPort port of the proxy server
79       * @param proxyUser username used to connect to the proxy server
80       * @param proxyPassword password used to connect to the proxy server
81       */
82      public SVNBasicAuthenticationManager(List<SVNAuthentication> authnMethods, String proxyHost, int proxyPort,
83              String proxyUser, String proxyPassword) {
84          connectionTimeout = 5000;
85          readTimeout = 10000;
86          setAuthenticationMethods(authnMethods);
87          proxyManager = new BasicProxyManager(proxyHost, proxyPort, proxyUser, proxyPassword);
88      }
89  
90      /** {@inheritDoc} */
91      public void acknowledgeAuthentication(boolean authnAccepted, String authnKind, String authnRealm,
92              SVNErrorMessage error, SVNAuthentication authnMethods) throws SVNException {
93          if (authnAccepted) {
94              log.trace("Successful authentication to SVN repository with {} credentials", authnKind);
95          } else {
96              log.trace("Unable to authenticate to SVN repository with {} credentials", authnKind);
97          }
98      }
99  
100     /** {@inheritDoc} */
101     public void acknowledgeTrustManager(TrustManager manager) {
102         log.debug("HTTPS connectiont trusted by trust manager");
103     }
104 
105     /** {@inheritDoc} */
106     public int getConnectTimeout(SVNRepository repository) {
107         return connectionTimeout;
108     }
109 
110     /**
111      * Sets the network connection timeout in milliseconds. If a value of zero or less is given than the value
112      * {@link Integer#MAX_VALUE} will be used.
113      * 
114      * @param timeout network connection timeout in milliseconds
115      */
116     public void setConnectionTimeout(int timeout) {
117         if (timeout <= 0) {
118             connectionTimeout = Integer.MAX_VALUE;
119         } else {
120             connectionTimeout = timeout;
121         }
122     }
123 
124     /** {@inheritDoc} */
125     public SVNAuthentication getFirstAuthentication(String authnKind, String authnRealm, SVNURL repository)
126             throws SVNException {
127         return authenticationMethods.get(authnKind);
128     }
129 
130     /** {@inheritDoc} */
131     public SVNAuthentication getNextAuthentication(String authnKind, String authnRealm, SVNURL respository)
132             throws SVNException {
133         return null;
134     }
135 
136     /** {@inheritDoc} */
137     public ISVNProxyManager getProxyManager(SVNURL repository) throws SVNException {
138         return proxyManager;
139     }
140 
141     /** {@inheritDoc} */
142     public int getReadTimeout(SVNRepository repository) {
143         return readTimeout;
144     }
145 
146     /**
147      * Sets the read operation timeout in milliseconds. If a value of zero or less is given than the value
148      * {@link Integer#MAX_VALUE} will be used.
149      * 
150      * @param timeout network connection timeout in milliseconds
151      */
152     public void setReadTimeout(int timeout) {
153         if (timeout <= 0) {
154             readTimeout = Integer.MAX_VALUE;
155         } else {
156             readTimeout = timeout;
157         }
158     }
159 
160     /** {@inheritDoc} */
161     public TrustManager getTrustManager(SVNURL respository) throws SVNException {
162         return trustManager;
163     }
164 
165     /**
166      * Sets the trust manager used when negotiating SSL/TLS connections.
167      * 
168      * @param manager trust manager used when negotiating SSL/TLS connections
169      */
170     public void setTrustManager(TrustManager manager) {
171         trustManager = manager;
172     }
173 
174     /** {@inheritDoc} */
175     public boolean isAuthenticationForced() {
176         return false;
177     }
178 
179     /** {@inheritDoc} */
180     public void setAuthenticationProvider(ISVNAuthenticationProvider arg0) {
181     }
182 
183     /**
184      * Sets the user authentication methods.
185      * 
186      * @param authnMethods user authentication methods
187      */
188     private void setAuthenticationMethods(List<SVNAuthentication> authnMethods) {
189         if (authnMethods == null || authnMethods.size() == 0) {
190             authenticationMethods = Collections.emptyMap();
191         } else {
192             HashMap<String, SVNAuthentication> methods = new HashMap<String, SVNAuthentication>();
193             for (SVNAuthentication method : authnMethods) {
194                 if (methods.containsKey(method.getKind())) {
195                     log.warn("An authentication method of type " + method.getKind()
196                             + " has already been set, only the first will be used");
197                 } else {
198                     methods.put(method.getKind(), method);
199                 }
200             }
201             authenticationMethods = Collections.unmodifiableMap(methods);
202         }
203     }
204 
205     /** Basic implementation of {@link ISVNProxyManager}. */
206     private class BasicProxyManager implements ISVNProxyManager {
207 
208         /** Host name or IP address of the proxy. */
209         private final String host;
210 
211         /** Port of the proxy. */
212         private final int port;
213 
214         /** Username used to connect to the proxy. */
215         private final String user;
216 
217         /** Password used to connect to the proxy. */
218         private final String password;
219 
220         /**
221          * Constructor.
222          * 
223          * @param host host name or IP address of the proxy server
224          * @param port port of the proxy server
225          * @param user username used to connect to the proxy server
226          * @param password password used to connect to the proxy server
227          */
228         public BasicProxyManager(String host, int port, String user, String password) {
229             this.host = DatatypeHelper.safeTrimOrNullString(host);
230             if (this.host == null) {
231                 throw new IllegalArgumentException("Proxy host may not be null or empty");
232             }
233 
234             this.port = port;
235 
236             this.user = DatatypeHelper.safeTrimOrNullString(user);
237             this.password = DatatypeHelper.safeTrimOrNullString(password);
238         }
239 
240         /** {@inheritDoc} */
241         public void acknowledgeProxyContext(boolean accepted, SVNErrorMessage error) {
242             if (accepted) {
243                 log.trace("Connected to HTTP proxy " + host + ":" + port);
244             }
245             log.error("Unable to connect to HTTP proxy " + host + ":" + port + " recieved error:\n"
246                     + error.getFullMessage());
247         }
248 
249         /** {@inheritDoc} */
250         public String getProxyHost() {
251             return host;
252         }
253 
254         /** {@inheritDoc} */
255         public String getProxyPassword() {
256             return password;
257         }
258 
259         /** {@inheritDoc} */
260         public int getProxyPort() {
261             return port;
262         }
263 
264         /** {@inheritDoc} */
265         public String getProxyUserName() {
266             return user;
267         }
268     }
269 }