mirror of
https://github.com/owncloud/android-library.git
synced 2026-08-13 17:32:56 +00:00
Merge branch 'develop' of github.com:owncloud/android-library into buildsystem/gradle_develop
Conflicts: .travis.yml
This commit is contained in:
@@ -30,6 +30,7 @@ import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.httpclient.Cookie;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HostConfiguration;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpConnectionManager;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
@@ -92,11 +93,33 @@ public class OwnCloudClient extends HttpClient {
|
||||
PARAM_SINGLE_COOKIE_HEADER, // to avoid problems with some web servers
|
||||
PARAM_SINGLE_COOKIE_HEADER_VALUE);
|
||||
|
||||
applyProxySettings();
|
||||
|
||||
clearCredentials();
|
||||
}
|
||||
|
||||
|
||||
public void setCredentials(OwnCloudCredentials credentials) {
|
||||
private void applyProxySettings() {
|
||||
String proxyHost = System.getProperty("http.proxyHost");
|
||||
String proxyPortSt = System.getProperty("http.proxyPort");
|
||||
int proxyPort = 0;
|
||||
try {
|
||||
if (proxyPortSt != null && proxyPortSt.length() > 0) {
|
||||
proxyPort = Integer.parseInt(proxyPortSt);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
if (proxyHost != null && proxyHost.length() > 0) {
|
||||
HostConfiguration hostCfg = getHostConfiguration();
|
||||
hostCfg.setProxy(proxyHost, proxyPort);
|
||||
Log_OC.d(TAG, "Proxy settings: " + proxyHost + ":" + proxyPort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setCredentials(OwnCloudCredentials credentials) {
|
||||
if (credentials != null) {
|
||||
mCredentials = credentials;
|
||||
mCredentials.applyTo(this);
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
@@ -43,6 +44,7 @@ import javax.net.ssl.SSLSocket;
|
||||
import org.apache.commons.httpclient.ConnectTimeoutException;
|
||||
import org.apache.commons.httpclient.params.HttpConnectionParams;
|
||||
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
|
||||
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
|
||||
import org.apache.http.conn.ssl.X509HostnameVerifier;
|
||||
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
@@ -56,7 +58,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
|
||||
public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
public class AdvancedSslSocketFactory implements SecureProtocolSocketFactory {
|
||||
|
||||
private static final String TAG = AdvancedSslSocketFactory.class.getSimpleName();
|
||||
|
||||
@@ -71,11 +73,17 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
/**
|
||||
* Constructor for AdvancedSSLProtocolSocketFactory.
|
||||
*/
|
||||
public AdvancedSslSocketFactory(SSLContext sslContext, AdvancedX509TrustManager trustManager, X509HostnameVerifier hostnameVerifier) {
|
||||
public AdvancedSslSocketFactory(
|
||||
SSLContext sslContext, AdvancedX509TrustManager trustManager, X509HostnameVerifier hostnameVerifier
|
||||
) {
|
||||
|
||||
if (sslContext == null)
|
||||
throw new IllegalArgumentException("AdvancedSslSocketFactory can not be created with a null SSLContext");
|
||||
if (trustManager == null)
|
||||
throw new IllegalArgumentException("AdvancedSslSocketFactory can not be created with a null Trust Manager");
|
||||
if (trustManager == null && mHostnameVerifier != null)
|
||||
throw new IllegalArgumentException(
|
||||
"AdvancedSslSocketFactory can not be created with a null Trust Manager and a " +
|
||||
"not null Hostname Verifier"
|
||||
);
|
||||
mSslContext = sslContext;
|
||||
mTrustManager = trustManager;
|
||||
mHostnameVerifier = hostnameVerifier;
|
||||
@@ -84,8 +92,11 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
/**
|
||||
* @see ProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
|
||||
*/
|
||||
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
|
||||
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
|
||||
throws IOException, UnknownHostException {
|
||||
|
||||
Socket socket = mSslContext.getSocketFactory().createSocket(host, port, clientHost, clientPort);
|
||||
enableSecureProtocols(socket);
|
||||
verifyPeerIdentity(host, port, socket);
|
||||
return socket;
|
||||
}
|
||||
@@ -150,7 +161,8 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
final InetAddress localAddress, final int localPort,
|
||||
final HttpConnectionParams params) throws IOException,
|
||||
UnknownHostException, ConnectTimeoutException {
|
||||
Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port + ", local " + localAddress + ":" + localPort + ", params: " + params);
|
||||
Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port + ", local " + localAddress + ":" +
|
||||
localPort + ", params: " + params);
|
||||
if (params == null) {
|
||||
throw new IllegalArgumentException("Parameters may not be null");
|
||||
}
|
||||
@@ -161,6 +173,7 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
SocketFactory socketfactory = mSslContext.getSocketFactory();
|
||||
Log_OC.d(TAG, " ... with connection timeout " + timeout + " and socket timeout " + params.getSoTimeout());
|
||||
Socket socket = socketfactory.createSocket();
|
||||
enableSecureProtocols(socket);
|
||||
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
|
||||
SocketAddress remoteaddr = new InetSocketAddress(host, port);
|
||||
socket.setSoTimeout(params.getSoTimeout());
|
||||
@@ -178,10 +191,22 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
UnknownHostException {
|
||||
Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port);
|
||||
Socket socket = mSslContext.getSocketFactory().createSocket(host, port);
|
||||
enableSecureProtocols(socket);
|
||||
verifyPeerIdentity(host, port, socket);
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
|
||||
UnknownHostException {
|
||||
Socket sslSocket = mSslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
|
||||
enableSecureProtocols(sslSocket);
|
||||
verifyPeerIdentity(host, port, sslSocket);
|
||||
return sslSocket;
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return ((obj != null) && obj.getClass().equals(
|
||||
AdvancedSslSocketFactory.class));
|
||||
@@ -206,13 +231,15 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
*
|
||||
* The server certificate is verified first.
|
||||
*
|
||||
* Then, the host name is compared with the content of the server certificate using the current host name verifier, if any.
|
||||
* Then, the host name is compared with the content of the server certificate using the current host name verifier,
|
||||
* if any.
|
||||
* @param socket
|
||||
*/
|
||||
private void verifyPeerIdentity(String host, int port, Socket socket) throws IOException {
|
||||
try {
|
||||
CertificateCombinedException failInHandshake = null;
|
||||
/// 1. VERIFY THE SERVER CERTIFICATE through the registered TrustManager (that should be an instance of AdvancedX509TrustManager)
|
||||
/// 1. VERIFY THE SERVER CERTIFICATE through the registered TrustManager
|
||||
/// (that should be an instance of AdvancedX509TrustManager)
|
||||
try {
|
||||
SSLSocket sock = (SSLSocket) socket; // a new SSLSession instance is created as a "side effect"
|
||||
sock.startHandshake();
|
||||
@@ -224,7 +251,9 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
} else {
|
||||
Throwable cause = e.getCause();
|
||||
Throwable previousCause = null;
|
||||
while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) {
|
||||
while ( cause != null &&
|
||||
cause != previousCause &&
|
||||
!(cause instanceof CertificateCombinedException)) {
|
||||
previousCause = cause;
|
||||
cause = cause.getCause();
|
||||
}
|
||||
@@ -263,9 +292,13 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
|
||||
/// 3. Combine the exceptions to throw, if any
|
||||
if (!verifiedHostname) {
|
||||
SSLPeerUnverifiedException pue = new SSLPeerUnverifiedException("Names in the server certificate do not match to " + host + " in the URL");
|
||||
SSLPeerUnverifiedException pue = new SSLPeerUnverifiedException(
|
||||
"Names in the server certificate do not match to " + host + " in the URL"
|
||||
);
|
||||
if (failInHandshake == null) {
|
||||
failInHandshake = new CertificateCombinedException((X509Certificate) newSession.getPeerCertificates()[0]);
|
||||
failInHandshake = new CertificateCombinedException(
|
||||
(X509Certificate) newSession.getPeerCertificates()[0]
|
||||
);
|
||||
failInHandshake.setHostInUrl(host);
|
||||
}
|
||||
failInHandshake.setSslPeerUnverifiedException(pue);
|
||||
@@ -287,5 +320,23 @@ public class AdvancedSslSocketFactory implements ProtocolSocketFactory {
|
||||
throw io;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grants that all protocols supported by the Security Provider in mSslContext are enabled in socket.
|
||||
*
|
||||
* Grants also that no unsupported protocol is tried to be enabled. That would trigger an exception, breaking
|
||||
* the connection process although some protocols are supported.
|
||||
*
|
||||
* This is not cosmetic: not all the supported protocols are enabled by default. Too see an overview of
|
||||
* supported and enabled protocols in the stock Security Provider in Android see the tables in
|
||||
* http://developer.android.com/reference/javax/net/ssl/SSLSocket.html.
|
||||
*
|
||||
* @param socket
|
||||
*/
|
||||
private void enableSecureProtocols(Socket socket) {
|
||||
SSLParameters params = mSslContext.getSupportedSSLParameters();
|
||||
String [] supportedProtocols = params.getProtocols();
|
||||
((SSLSocket) socket).setEnabledProtocols(supportedProtocols);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,6 +57,12 @@ public class NetworkUtils {
|
||||
|
||||
/** Default timeout for establishing a connection */
|
||||
public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;
|
||||
|
||||
/** Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API */
|
||||
public static final String PROTOCOL_TLSv1_2 = "TLSv1.2";
|
||||
|
||||
/** Standard name for protocol TLS version 1.0 in JSSE API */
|
||||
public static final String PROTOCOL_TLSv1_0 = "TLSv1";
|
||||
|
||||
/** Connection manager for all the OwnCloudClients */
|
||||
private static MultiThreadedHttpConnectionManager mConnManager = null;
|
||||
@@ -72,7 +78,9 @@ public class NetworkUtils {
|
||||
* Registers or unregisters the proper components for advanced SSL handling.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void registerAdvancedSslContext(boolean register, Context context) throws GeneralSecurityException, IOException {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void registerAdvancedSslContext(boolean register, Context context)
|
||||
throws GeneralSecurityException, IOException {
|
||||
Protocol pr = null;
|
||||
try {
|
||||
pr = Protocol.getProtocol("https");
|
||||
@@ -93,13 +101,22 @@ public class NetworkUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static AdvancedSslSocketFactory getAdvancedSslSocketFactory(Context context) throws GeneralSecurityException, IOException {
|
||||
public static AdvancedSslSocketFactory getAdvancedSslSocketFactory(Context context)
|
||||
throws GeneralSecurityException, IOException {
|
||||
if (mAdvancedSslSocketFactory == null) {
|
||||
KeyStore trustStore = getKnownServersStore(context);
|
||||
AdvancedX509TrustManager trustMgr = new AdvancedX509TrustManager(trustStore);
|
||||
TrustManager[] tms = new TrustManager[] { trustMgr };
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
SSLContext sslContext;
|
||||
try {
|
||||
sslContext = SSLContext.getInstance("TLSv1.2");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
Log_OC.w(TAG, "TLSv1.2 is not supported in this device; falling through TLSv1.0");
|
||||
sslContext = SSLContext.getInstance("TLSv1");
|
||||
// should be available in any device; see reference of supported protocols in
|
||||
// http://developer.android.com/reference/javax/net/ssl/SSLSocket.html
|
||||
}
|
||||
sslContext.init(null, tms, null);
|
||||
|
||||
mHostnameVerifier = new BrowserCompatHostnameVerifier();
|
||||
@@ -127,9 +144,11 @@ public class NetworkUtils {
|
||||
* @throws KeyStoreException When the KeyStore instance could not be created.
|
||||
* @throws IOException When an existing local trust store could not be loaded.
|
||||
* @throws NoSuchAlgorithmException When the existing local trust store was saved with an unsupported algorithm.
|
||||
* @throws CertificateException When an exception occurred while loading the certificates from the local trust store.
|
||||
* @throws CertificateException When an exception occurred while loading the certificates from the local
|
||||
* trust store.
|
||||
*/
|
||||
private static KeyStore getKnownServersStore(Context context) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
|
||||
private static KeyStore getKnownServersStore(Context context)
|
||||
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
|
||||
if (mKnownServersStore == null) {
|
||||
//mKnownServersStore = KeyStore.getInstance("BKS");
|
||||
mKnownServersStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
@@ -143,15 +162,17 @@ public class NetworkUtils {
|
||||
in.close();
|
||||
}
|
||||
} else {
|
||||
mKnownServersStore.load(null, LOCAL_TRUSTSTORE_PASSWORD.toCharArray()); // necessary to initialize an empty KeyStore instance
|
||||
// next is necessary to initialize an empty KeyStore instance
|
||||
mKnownServersStore.load(null, LOCAL_TRUSTSTORE_PASSWORD.toCharArray());
|
||||
}
|
||||
}
|
||||
return mKnownServersStore;
|
||||
}
|
||||
|
||||
|
||||
public static void addCertToKnownServersStore(Certificate cert, Context context) throws KeyStoreException, NoSuchAlgorithmException,
|
||||
CertificateException, IOException {
|
||||
public static void addCertToKnownServersStore(Certificate cert, Context context)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
||||
|
||||
KeyStore knownServers = getKnownServersStore(context);
|
||||
knownServers.setCertificateEntry(Integer.toString(cert.hashCode()), cert);
|
||||
FileOutputStream fos = null;
|
||||
@@ -173,7 +194,8 @@ public class NetworkUtils {
|
||||
return mConnManager;
|
||||
}
|
||||
|
||||
public static boolean isCertInKnownServersStore(Certificate cert, Context context) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
||||
public static boolean isCertInKnownServersStore(Certificate cert, Context context)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
||||
|
||||
KeyStore knownServers = getKnownServersStore(context);
|
||||
Log_OC.d(TAG, "Certificate - HashCode: " + cert.hashCode() + " "
|
||||
|
||||
@@ -175,5 +175,4 @@ public class Log_OC {
|
||||
public static String[] getLogFileNames() {
|
||||
return mLogFileNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
public class ReadRemoteFileOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
|
||||
private static final int SYNC_READ_TIMEOUT = 10000;
|
||||
private static final int SYNC_READ_TIMEOUT = 40000;
|
||||
private static final int SYNC_CONNECTION_TIMEOUT = 5000;
|
||||
|
||||
private String mRemotePath;
|
||||
|
||||
Reference in New Issue
Block a user