diff options
author | Tobias Kaminsky <tobias@kaminsky.me> | 2020-02-03 10:18:29 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-03 10:18:29 +0300 |
commit | 5c3651d0b4317d93c2957ab3d9aa10d376265c83 (patch) | |
tree | 0eb9660614fea2083187e44e7a7e44b3ad2dad65 | |
parent | 07408240d2a5f982702ecff90f461b84c9388dfe (diff) | |
parent | 73d3d4a3591db4855599bbaf1c173b6fa012004b (diff) |
Merge pull request #392 from nextcloud/backport/388/stable-2.0rc-2.0.1-012.0.1stable-2.0
[stable-2.0] Allow self-signed certs
-rw-r--r-- | .drone.yml | 6 | ||||
-rw-r--r-- | gradle.properties | 2 | ||||
-rw-r--r-- | src/androidTest/java/com/owncloud/android/AbstractIT.java | 57 | ||||
-rw-r--r-- | src/main/java/com/nextcloud/common/NextcloudClient.kt | 43 | ||||
-rw-r--r-- | src/main/java/com/nextcloud/common/OkHttpMethodBase.kt | 2 | ||||
-rw-r--r-- | src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java | 2 |
6 files changed, 93 insertions, 19 deletions
@@ -88,9 +88,9 @@ steps: services: - name: server - image: nextcloudci/server:server-13 + image: nextcloudci/server:server-17 commands: - - /initnc.sh + - /usr/local/bin/initnc.sh - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1" - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2" - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3" @@ -102,7 +102,7 @@ services: - su www-data -c "php /var/www/html/occ app:enable activity" - su www-data -c "git clone -b master https://github.com/nextcloud/text.git /var/www/html/apps/text/" - su www-data -c "php /var/www/html/occ app:enable text" - - /run.sh + - /usr/local/bin/run.sh trigger: branch: diff --git a/gradle.properties b/gradle.properties index e22ec2e3..00ea3cc5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # can be overriden by ~/.gradle/gradle.properties -NC_TEST_SERVER_BASEURL=http://server +NC_TEST_SERVER_BASEURL=https://server NC_TEST_SERVER_USERNAME=test NC_TEST_SERVER_PASSWORD=test android.enableJetifier=true diff --git a/src/androidTest/java/com/owncloud/android/AbstractIT.java b/src/androidTest/java/com/owncloud/android/AbstractIT.java index cec8d8d4..3d5603f2 100644 --- a/src/androidTest/java/com/owncloud/android/AbstractIT.java +++ b/src/androidTest/java/com/owncloud/android/AbstractIT.java @@ -35,10 +35,14 @@ import com.owncloud.android.lib.common.OwnCloudBasicCredentials; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientFactory; import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.network.CertificateCombinedException; +import com.owncloud.android.lib.common.network.NetworkUtils; import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation; import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation; import com.owncloud.android.lib.resources.files.model.RemoteFile; +import com.owncloud.android.lib.resources.status.GetStatusRemoteOperation; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -48,6 +52,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import androidx.test.platform.app.InstrumentationRegistry; import okhttp3.Credentials; @@ -63,14 +71,19 @@ public abstract class AbstractIT { public static OwnCloudClient client; protected static NextcloudClient nextcloudClient; - private static Context context; + protected static Context context; protected String baseFolderPath = "/test_for_build/"; public static final String ASSETS__TEXT_FILE_NAME = "textFile.txt"; + private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks"; @BeforeClass - public static void beforeAll() { + public static void beforeAll() throws InterruptedException, + CertificateException, + NoSuchAlgorithmException, + KeyStoreException, + IOException { Bundle arguments = InstrumentationRegistry.getArguments(); context = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -87,6 +100,43 @@ public abstract class AbstractIT { nextcloudClient = new NextcloudClient(url, context); nextcloudClient.credentials = Credentials.basic(loginName, password); nextcloudClient.userId = loginName; // for test same as userId + + testConnection(); + } + + private static void testConnection() throws KeyStoreException, + CertificateException, + NoSuchAlgorithmException, + IOException, + InterruptedException { + GetStatusRemoteOperation getStatus = new GetStatusRemoteOperation(context); + + RemoteOperationResult result = getStatus.execute(client); + + if (result.isSuccess()) { + Log_OC.d("AbstractIT", "Connection to server successful"); + } else { + if (RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(result.getCode())) { + Log_OC.d("AbstractIT", "Accepting certificate"); + + CertificateCombinedException exception = (CertificateCombinedException) result.getException(); + X509Certificate certificate = exception.getServerCertificate(); + + NetworkUtils.addCertToKnownServersStore(certificate, context); + Thread.sleep(1000); + + // retry + getStatus = new GetStatusRemoteOperation(context); + result = getStatus.execute(client); + + if (!result.isSuccess()) { + throw new RuntimeException("No connection to server possible, even with accepted cert"); + } + + } else { + throw new RuntimeException("No connection to server possible: " + result.getCode()); + } + } } public String createFile(String name) throws IOException { @@ -150,6 +200,9 @@ public abstract class AbstractIT { .execute(client).isSuccess()); } } + + // delete keystore + new File(context.getFilesDir(), LOCAL_TRUSTSTORE_FILENAME).delete(); } public static File getFile(String filename) throws IOException { diff --git a/src/main/java/com/nextcloud/common/NextcloudClient.kt b/src/main/java/com/nextcloud/common/NextcloudClient.kt index 36a034d7..4e05190a 100644 --- a/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -30,8 +30,10 @@ package com.nextcloud.common import android.content.Context import android.net.Uri import com.owncloud.android.lib.common.OwnCloudClient -import com.owncloud.android.lib.common.OwnCloudClientFactory +import com.owncloud.android.lib.common.OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT_LONG import com.owncloud.android.lib.common.accounts.AccountUtils +import com.owncloud.android.lib.common.network.AdvancedX509TrustManager +import com.owncloud.android.lib.common.network.NetworkUtils import com.owncloud.android.lib.common.network.RedirectionPath import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult @@ -39,26 +41,41 @@ import com.owncloud.android.lib.common.utils.Log_OC import okhttp3.CookieJar import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.Response import org.apache.commons.httpclient.HttpStatus import java.io.IOException import java.util.concurrent.TimeUnit +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSession +import javax.net.ssl.TrustManager -class NextcloudClient(var baseUri: Uri, val context: Context) : OkHttpClient() { - companion object { - @JvmStatic - val TAG = NextcloudClient::class.java.simpleName - } - - var client: OkHttpClient = Builder() - .cookieJar(CookieJar.NO_COOKIES) - .callTimeout(OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT_LONG, TimeUnit.MILLISECONDS) - .build() +class NextcloudClient(var baseUri: Uri, val context: Context) { lateinit var credentials: String lateinit var userId: String lateinit var request: Request var followRedirects = true; + val client: OkHttpClient + + companion object { + @JvmStatic + val TAG = NextcloudClient::class.java.simpleName + } + + init { + val trustManager = AdvancedX509TrustManager(NetworkUtils.getKnownServersStore(context)) + val sslContext = SSLContext.getInstance("TLSv1") + sslContext.init(null, arrayOf<TrustManager>(trustManager), null) + val sslSocketFactory = sslContext.socketFactory + client = OkHttpClient.Builder() + .cookieJar(CookieJar.NO_COOKIES) + .callTimeout(DEFAULT_DATA_TIMEOUT_LONG, TimeUnit.MILLISECONDS) + .sslSocketFactory(sslSocketFactory, trustManager) + .hostnameVerifier { asdf: String?, usdf: SSLSession? -> true } + .build() + } + fun execute(remoteOperation: RemoteOperation): RemoteOperationResult { return remoteOperation.run(this) } @@ -67,6 +84,10 @@ class NextcloudClient(var baseUri: Uri, val context: Context) : OkHttpClient() { return method.execute(this) } + fun execute(request: Request): Response { + return client.newCall(request).execute() + } + fun getRequestHeader(name: String): String? { return request.header(name) } diff --git a/src/main/java/com/nextcloud/common/OkHttpMethodBase.kt b/src/main/java/com/nextcloud/common/OkHttpMethodBase.kt index 4e7ba3b3..30d956ee 100644 --- a/src/main/java/com/nextcloud/common/OkHttpMethodBase.kt +++ b/src/main/java/com/nextcloud/common/OkHttpMethodBase.kt @@ -123,7 +123,7 @@ abstract class OkHttpMethodBase(var uri: String, val request = temp.build() - response = nextcloudClient.newCall(request).execute() + response = nextcloudClient.client.newCall(request).execute() if (nextcloudClient.followRedirects) { return nextcloudClient.followRedirection(this).getLastStatus() diff --git a/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java b/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java index 41284080..19005160 100644 --- a/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java +++ b/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java @@ -147,7 +147,7 @@ public class NetworkUtils { * @throws CertificateException When an exception occurred while loading the certificates from the local * trust store. */ - private static KeyStore getKnownServersStore(Context context) + public static KeyStore getKnownServersStore(Context context) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { if (mKnownServersStore == null) { //mKnownServersStore = KeyStore.getInstance("BKS"); |