Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit a58c9481 authored by Tobias Kaminsky's avatar Tobias Kaminsky Committed by GitHub
Browse files

Merge pull request #388 from nextcloud/ssl

Allow self-signed certs
parents 721c01bc 6fa2ee71
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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:
+1 −1
Original line number Diff line number Diff line
# 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
+55 −2
Original line number Diff line number Diff line
@@ -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 {
+32 −11
Original line number Diff line number Diff line
@@ -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,25 +41,40 @@ 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) {
    lateinit var credentials: String
    lateinit var userId: String
    lateinit var request: Request
    var followRedirects = true;
    val client: OkHttpClient
    
class NextcloudClient(var baseUri: Uri, val context: Context) : OkHttpClient() {
    companion object {
        @JvmStatic
        val TAG = NextcloudClient::class.java.simpleName
    }

    var client: OkHttpClient = Builder()
    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(OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT_LONG, TimeUnit.MILLISECONDS)
                .callTimeout(DEFAULT_DATA_TIMEOUT_LONG, TimeUnit.MILLISECONDS)
                .sslSocketFactory(sslSocketFactory, trustManager)
                .hostnameVerifier { asdf: String?, usdf: SSLSession? -> true }
                .build()

    lateinit var credentials: String
    lateinit var userId: String
    lateinit var request: Request
    var followRedirects = true;
    }
   
    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)
    }
+1 −1
Original line number Diff line number Diff line
@@ -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()
Loading