Loading CHANGELOG.md +10 −0 Original line number Diff line number Diff line # Version 2.x ## Version 2.0 - now uses okhttp 4.5.0, which requires Android 5 - removed deprecated methods If you need support for older Android versions, stay with 1.x. # Version 1.x ## Version 1.0.1 Loading build.gradle.kts +8 −7 Original line number Diff line number Diff line Loading @@ -2,10 +2,7 @@ import org.jetbrains.dokka.gradle.DokkaTask object Libs { // okhttp HTTP library // We'll use 3.12 for now, but this branch won't receive feature updates anymore. Security // updates are limited to Dec 2020, so we'll have to update to 3.13 until then. On Android, // using 3.13 will raise the required SDK level to Android 5. const val okhttpVersion = "3.12.8" const val okhttpVersion = "4.5.0" // XmlPullParser library const val xpp3Version = "1.1.6" Loading @@ -18,7 +15,7 @@ repositories { } plugins { kotlin("jvm") version "1.3.61" kotlin("jvm") version "1.3.71" id("com.github.kukuhyoniatmoko.buildconfigkotlin") version "1.0.5" id("org.jetbrains.dokka") version "0.10.0" Loading @@ -39,13 +36,17 @@ tasks { dependencies { implementation(kotlin("stdlib")) // okhttp api(platform("com.squareup.okhttp3:okhttp-bom:${Libs.okhttpVersion}")) api("com.squareup.okhttp3:okhttp") // use Kotlin-friendly okhttp 2.x implementation("com.squareup.okio:okio:2.+") api("com.squareup.okhttp3:okhttp:${Libs.okhttpVersion}") implementation("org.apache.commons:commons-lang3:3.9") api("org.ogce:xpp3:${Libs.xpp3Version}") testImplementation("com.squareup.okhttp3:mockwebserver:${Libs.okhttpVersion}") testImplementation("com.squareup.okhttp3:mockwebserver") } buildConfigKotlin { Loading gradle/wrapper/gradle-wrapper.properties +1 −1 Original line number Diff line number Diff line Loading @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip src/main/kotlin/at/bitfire/dav4jvm/BasicDigestAuthHandler.kt +20 −22 Original line number Diff line number Diff line Loading @@ -9,12 +9,10 @@ package at.bitfire.dav4jvm import okhttp3.* import okhttp3.Response import okio.Buffer import okio.ByteString import okio.ByteString.Companion.toByteString import java.io.IOException import java.nio.ByteBuffer import java.util.* import java.util.concurrent.atomic.AtomicInteger import okio.ByteString.Companion.toByteString /** * Handler to manage authentication against a given service (may be limited to one domain). Loading Loading @@ -60,7 +58,7 @@ class BasicDigestAuthHandler( fun authenticateRequest(request: Request, response: Response?): Request? { domain?.let { val host = request.url().host() val host = request.url.host if (!domain.equals(UrlUtils.hostToDomain(host), true)) { Constants.log.warning("Not authenticating against $host because it doesn't belong to $domain") return null Loading @@ -82,7 +80,7 @@ class BasicDigestAuthHandler( var newDigestAuth: Challenge? = null for (challenge in response.challenges()) when { "Basic".equals(challenge.scheme(), true) -> { "Basic".equals(challenge.scheme, true) -> { basicAuth?.let { Constants.log.warning("Basic credentials didn't work last time -> aborting") basicAuth = null Loading @@ -90,8 +88,8 @@ class BasicDigestAuthHandler( } newBasicAuth = challenge } "Digest".equals(challenge.scheme(), true) -> { if (digestAuth != null && !"true".equals(challenge.authParams()["stale"], true)) { "Digest".equals(challenge.scheme, true) -> { if (digestAuth != null && !"true".equals(challenge.authParams["stale"], true)) { Constants.log.warning("Digest credentials didn't work last time and server nonce has not expired -> aborting") digestAuth = null return null Loading @@ -107,12 +105,12 @@ class BasicDigestAuthHandler( // we MUST prefer Digest auth [https://tools.ietf.org/html/rfc2617#section-4.6] when { digestAuth != null -> { Constants.log.fine("Adding Digest authorization request for ${request.url()}") Constants.log.fine("Adding Digest authorization request for ${request.url}") return digestRequest(request, digestAuth) } basicAuth != null -> { Constants.log.fine("Adding Basic authorization header for ${request.url()}") Constants.log.fine("Adding Basic authorization header for ${request.url}") /* In RFC 2617 (obsolete), there was no encoding for credentials defined, although one can interpret it as "use ISO-8859-1 encoding". This has been clarified by RFC 7617, Loading @@ -135,12 +133,12 @@ class BasicDigestAuthHandler( if (digest == null) return null val realm = digest.authParams()["realm"] val opaque = digest.authParams()["opaque"] val nonce = digest.authParams()["nonce"] val realm = digest.authParams["realm"] val opaque = digest.authParams["opaque"] val nonce = digest.authParams["nonce"] val algorithm = Algorithm.determine(digest.authParams()["algorithm"]) val qop = Protection.selectFrom(digest.authParams()["qop"]) val algorithm = Algorithm.determine(digest.authParams["algorithm"]) val qop = Protection.selectFrom(digest.authParams["qop"]) // build response parameters var response: String? = null Loading @@ -165,8 +163,8 @@ class BasicDigestAuthHandler( if (algorithm != null) params.add("algorithm=${quotedString(algorithm.algorithm)}") val method = request.method() val digestURI = request.url().encodedPath() val method = request.method val digestURI = request.url.encodedPath params.add("uri=${quotedString(digestURI)}") if (qop != null) { Loading @@ -192,7 +190,7 @@ class BasicDigestAuthHandler( "$method:$digestURI" Protection.AuthInt -> { try { val body = request.body() val body = request.body "$method:$digestURI:" + (if (body != null) h(body) else h("")) } catch(e: IOException) { Constants.log.warning("Couldn't get entity-body for hash calculation") Loading Loading @@ -235,10 +233,10 @@ class BasicDigestAuthHandler( companion object { fun determine(paramValue: String?): Algorithm? { return when { paramValue == null || Algorithm.MD5.algorithm.equals(paramValue, true) -> Algorithm.MD5 Algorithm.MD5_SESSION.algorithm.equals(paramValue, true) -> Algorithm.MD5_SESSION paramValue == null || MD5.algorithm.equals(paramValue, true) -> MD5 MD5_SESSION.algorithm.equals(paramValue, true) -> MD5_SESSION else -> { Constants.log.warning("Ignoring unknown hash algorithm: $paramValue") null Loading Loading @@ -278,7 +276,7 @@ class BasicDigestAuthHandler( override fun authenticate(route: Route?, response: Response) = authenticateRequest(response.request(), response) authenticateRequest(response.request, response) override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() Loading src/main/kotlin/at/bitfire/dav4jvm/Constants.kt +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ package at.bitfire.dav4jvm import BuildConfig import java.util.logging.Logger object Constants { Loading Loading
CHANGELOG.md +10 −0 Original line number Diff line number Diff line # Version 2.x ## Version 2.0 - now uses okhttp 4.5.0, which requires Android 5 - removed deprecated methods If you need support for older Android versions, stay with 1.x. # Version 1.x ## Version 1.0.1 Loading
build.gradle.kts +8 −7 Original line number Diff line number Diff line Loading @@ -2,10 +2,7 @@ import org.jetbrains.dokka.gradle.DokkaTask object Libs { // okhttp HTTP library // We'll use 3.12 for now, but this branch won't receive feature updates anymore. Security // updates are limited to Dec 2020, so we'll have to update to 3.13 until then. On Android, // using 3.13 will raise the required SDK level to Android 5. const val okhttpVersion = "3.12.8" const val okhttpVersion = "4.5.0" // XmlPullParser library const val xpp3Version = "1.1.6" Loading @@ -18,7 +15,7 @@ repositories { } plugins { kotlin("jvm") version "1.3.61" kotlin("jvm") version "1.3.71" id("com.github.kukuhyoniatmoko.buildconfigkotlin") version "1.0.5" id("org.jetbrains.dokka") version "0.10.0" Loading @@ -39,13 +36,17 @@ tasks { dependencies { implementation(kotlin("stdlib")) // okhttp api(platform("com.squareup.okhttp3:okhttp-bom:${Libs.okhttpVersion}")) api("com.squareup.okhttp3:okhttp") // use Kotlin-friendly okhttp 2.x implementation("com.squareup.okio:okio:2.+") api("com.squareup.okhttp3:okhttp:${Libs.okhttpVersion}") implementation("org.apache.commons:commons-lang3:3.9") api("org.ogce:xpp3:${Libs.xpp3Version}") testImplementation("com.squareup.okhttp3:mockwebserver:${Libs.okhttpVersion}") testImplementation("com.squareup.okhttp3:mockwebserver") } buildConfigKotlin { Loading
gradle/wrapper/gradle-wrapper.properties +1 −1 Original line number Diff line number Diff line Loading @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
src/main/kotlin/at/bitfire/dav4jvm/BasicDigestAuthHandler.kt +20 −22 Original line number Diff line number Diff line Loading @@ -9,12 +9,10 @@ package at.bitfire.dav4jvm import okhttp3.* import okhttp3.Response import okio.Buffer import okio.ByteString import okio.ByteString.Companion.toByteString import java.io.IOException import java.nio.ByteBuffer import java.util.* import java.util.concurrent.atomic.AtomicInteger import okio.ByteString.Companion.toByteString /** * Handler to manage authentication against a given service (may be limited to one domain). Loading Loading @@ -60,7 +58,7 @@ class BasicDigestAuthHandler( fun authenticateRequest(request: Request, response: Response?): Request? { domain?.let { val host = request.url().host() val host = request.url.host if (!domain.equals(UrlUtils.hostToDomain(host), true)) { Constants.log.warning("Not authenticating against $host because it doesn't belong to $domain") return null Loading @@ -82,7 +80,7 @@ class BasicDigestAuthHandler( var newDigestAuth: Challenge? = null for (challenge in response.challenges()) when { "Basic".equals(challenge.scheme(), true) -> { "Basic".equals(challenge.scheme, true) -> { basicAuth?.let { Constants.log.warning("Basic credentials didn't work last time -> aborting") basicAuth = null Loading @@ -90,8 +88,8 @@ class BasicDigestAuthHandler( } newBasicAuth = challenge } "Digest".equals(challenge.scheme(), true) -> { if (digestAuth != null && !"true".equals(challenge.authParams()["stale"], true)) { "Digest".equals(challenge.scheme, true) -> { if (digestAuth != null && !"true".equals(challenge.authParams["stale"], true)) { Constants.log.warning("Digest credentials didn't work last time and server nonce has not expired -> aborting") digestAuth = null return null Loading @@ -107,12 +105,12 @@ class BasicDigestAuthHandler( // we MUST prefer Digest auth [https://tools.ietf.org/html/rfc2617#section-4.6] when { digestAuth != null -> { Constants.log.fine("Adding Digest authorization request for ${request.url()}") Constants.log.fine("Adding Digest authorization request for ${request.url}") return digestRequest(request, digestAuth) } basicAuth != null -> { Constants.log.fine("Adding Basic authorization header for ${request.url()}") Constants.log.fine("Adding Basic authorization header for ${request.url}") /* In RFC 2617 (obsolete), there was no encoding for credentials defined, although one can interpret it as "use ISO-8859-1 encoding". This has been clarified by RFC 7617, Loading @@ -135,12 +133,12 @@ class BasicDigestAuthHandler( if (digest == null) return null val realm = digest.authParams()["realm"] val opaque = digest.authParams()["opaque"] val nonce = digest.authParams()["nonce"] val realm = digest.authParams["realm"] val opaque = digest.authParams["opaque"] val nonce = digest.authParams["nonce"] val algorithm = Algorithm.determine(digest.authParams()["algorithm"]) val qop = Protection.selectFrom(digest.authParams()["qop"]) val algorithm = Algorithm.determine(digest.authParams["algorithm"]) val qop = Protection.selectFrom(digest.authParams["qop"]) // build response parameters var response: String? = null Loading @@ -165,8 +163,8 @@ class BasicDigestAuthHandler( if (algorithm != null) params.add("algorithm=${quotedString(algorithm.algorithm)}") val method = request.method() val digestURI = request.url().encodedPath() val method = request.method val digestURI = request.url.encodedPath params.add("uri=${quotedString(digestURI)}") if (qop != null) { Loading @@ -192,7 +190,7 @@ class BasicDigestAuthHandler( "$method:$digestURI" Protection.AuthInt -> { try { val body = request.body() val body = request.body "$method:$digestURI:" + (if (body != null) h(body) else h("")) } catch(e: IOException) { Constants.log.warning("Couldn't get entity-body for hash calculation") Loading Loading @@ -235,10 +233,10 @@ class BasicDigestAuthHandler( companion object { fun determine(paramValue: String?): Algorithm? { return when { paramValue == null || Algorithm.MD5.algorithm.equals(paramValue, true) -> Algorithm.MD5 Algorithm.MD5_SESSION.algorithm.equals(paramValue, true) -> Algorithm.MD5_SESSION paramValue == null || MD5.algorithm.equals(paramValue, true) -> MD5 MD5_SESSION.algorithm.equals(paramValue, true) -> MD5_SESSION else -> { Constants.log.warning("Ignoring unknown hash algorithm: $paramValue") null Loading Loading @@ -278,7 +276,7 @@ class BasicDigestAuthHandler( override fun authenticate(route: Route?, response: Response) = authenticateRequest(response.request(), response) authenticateRequest(response.request, response) override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() Loading
src/main/kotlin/at/bitfire/dav4jvm/Constants.kt +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ package at.bitfire.dav4jvm import BuildConfig import java.util.logging.Logger object Constants { Loading