View Javadoc

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