Skip to content

Commit

Permalink
Directly use java.util.Logger instead of keeping an instance in Dav4j…
Browse files Browse the repository at this point in the history
…vm object
  • Loading branch information
rfc2822 committed Jul 15, 2024
1 parent e5450fa commit ca363be
Show file tree
Hide file tree
Showing 23 changed files with 139 additions and 113 deletions.
44 changes: 24 additions & 20 deletions src/main/kotlin/at/bitfire/dav4jvm/BasicDigestAuthHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import java.util.LinkedList
import java.util.Locale
import java.util.UUID
import java.util.concurrent.atomic.AtomicInteger
import java.util.logging.Logger

/**
* Handler to manage authentication against a given service (may be limited to one domain).
Expand All @@ -33,13 +34,13 @@ import java.util.concurrent.atomic.AtomicInteger
* Usage: Set as authenticator *and* as network interceptor.
*/
class BasicDigestAuthHandler(
/** Authenticate only against hosts ending with this domain (may be null, which means no restriction) */
val domain: String?,
/** Authenticate only against hosts ending with this domain (may be null, which means no restriction) */
val domain: String?,

val username: String,
val password: String,
val username: String,
val password: String,

val insecurePreemptive: Boolean = false
val insecurePreemptive: Boolean = false
): Authenticator, Interceptor {

companion object {
Expand All @@ -64,13 +65,15 @@ class BasicDigestAuthHandler(
// cached authentication schemes
private var basicAuth: Challenge? = null
private var digestAuth: Challenge? = null

private val logger = Logger.getLogger(javaClass.name)


fun authenticateRequest(request: Request, response: Response?): Request? {
domain?.let {
val host = request.url.host
if (!domain.equals(UrlUtils.hostToDomain(host), true)) {
Dav4jvm.log.warning("Not authenticating against $host because it doesn't belong to $domain")
logger.warning("Not authenticating against $host because it doesn't belong to $domain")
return null
}
}
Expand All @@ -79,7 +82,7 @@ class BasicDigestAuthHandler(
// we're not processing a 401 response

if (basicAuth == null && digestAuth == null && (request.isHttps || insecurePreemptive)) {
Dav4jvm.log.fine("Trying Basic auth preemptively")
logger.fine("Trying Basic auth preemptively")
basicAuth = Challenge("Basic", "")
}

Expand All @@ -92,15 +95,15 @@ class BasicDigestAuthHandler(
when {
"Basic".equals(challenge.scheme, true) -> {
basicAuth?.let {
Dav4jvm.log.warning("Basic credentials didn't work last time -> aborting")
logger.warning("Basic credentials didn't work last time -> aborting")
basicAuth = null
return null
}
newBasicAuth = challenge
}
"Digest".equals(challenge.scheme, true) -> {
if (digestAuth != null && !"true".equals(challenge.authParams["stale"], true)) {
Dav4jvm.log.warning("Digest credentials didn't work last time and server nonce has not expired -> aborting")
logger.warning("Digest credentials didn't work last time and server nonce has not expired -> aborting")
digestAuth = null
return null
}
Expand All @@ -115,12 +118,12 @@ class BasicDigestAuthHandler(
// we MUST prefer Digest auth [https://tools.ietf.org/html/rfc2617#section-4.6]
when {
digestAuth != null -> {
Dav4jvm.log.fine("Adding Digest authorization request for ${request.url}")
logger.fine("Adding Digest authorization request for ${request.url}")
return digestRequest(request, digestAuth)
}

basicAuth != null -> {
Dav4jvm.log.fine("Adding Basic authorization header for ${request.url}")
logger.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,
Expand All @@ -133,7 +136,7 @@ class BasicDigestAuthHandler(
}

response != null ->
Dav4jvm.log.warning("No supported authentication scheme")
logger.warning("No supported authentication scheme")
}

return null
Expand All @@ -158,13 +161,13 @@ class BasicDigestAuthHandler(
if (realm != null)
params.add("realm=${quotedString(realm)}")
else {
Dav4jvm.log.warning("No realm provided, aborting Digest auth")
logger.warning("No realm provided, aborting Digest auth")
return null
}
if (nonce != null)
params.add("nonce=${quotedString(nonce)}")
else {
Dav4jvm.log.warning("No nonce provided, aborting Digest auth")
logger.warning("No nonce provided, aborting Digest auth")
return null
}
if (opaque != null)
Expand Down Expand Up @@ -193,7 +196,7 @@ class BasicDigestAuthHandler(
else ->
null
}
Dav4jvm.log.finer("A1=$a1")
logger.finer("A1=$a1")

val a2: String? = when (qop) {
Protection.Auth ->
Expand All @@ -203,18 +206,18 @@ class BasicDigestAuthHandler(
val body = request.body
"$method:$digestURI:" + (if (body != null) h(body) else h(""))
} catch(e: IOException) {
Dav4jvm.log.warning("Couldn't get entity-body for hash calculation")
logger.warning("Couldn't get entity-body for hash calculation")
null
}
}
}
Dav4jvm.log.finer("A2=$a2")
logger.finer("A2=$a2")

if (a1 != null && a2 != null)
response = kd(h(a1), "$nonce:$ncValue:$clientNonce:${qop.qop}:${h(a2)}")

} else {
Dav4jvm.log.finer("Using legacy Digest auth")
logger.finer("Using legacy Digest auth")

// legacy (backwards compatibility with RFC 2069)
if (algorithm == Algorithm.MD5) {
Expand All @@ -235,7 +238,7 @@ class BasicDigestAuthHandler(


private enum class Algorithm(
val algorithm: String
val algorithm: String
) {
MD5("MD5"),
MD5_SESSION("MD5-sess");
Expand All @@ -248,7 +251,8 @@ class BasicDigestAuthHandler(
MD5_SESSION.algorithm.equals(paramValue, true) ->
MD5_SESSION
else -> {
Dav4jvm.log.warning("Ignoring unknown hash algorithm: $paramValue")
val logger = Logger.getLogger(Algorithm::javaClass.name)
logger.warning("Ignoring unknown hash algorithm: $paramValue")
null
}
}
Expand Down
15 changes: 0 additions & 15 deletions src/main/kotlin/at/bitfire/dav4jvm/Dav4jvm.kt

This file was deleted.

9 changes: 5 additions & 4 deletions src/main/kotlin/at/bitfire/dav4jvm/DavAddressBook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import java.io.IOException
import java.io.StringWriter
import java.util.logging.Logger

@Suppress("unused")
class DavAddressBook @JvmOverloads constructor(
httpClient: OkHttpClient,
location: HttpUrl,
log: Logger = Dav4jvm.log
): DavCollection(httpClient, location, log) {
httpClient: OkHttpClient,
location: HttpUrl,
logger: Logger = Logger.getLogger(DavAddressBook::javaClass.name)
): DavCollection(httpClient, location, logger) {

companion object {
val MIME_JCARD = "application/vcard+json".toMediaType()
Expand Down
9 changes: 5 additions & 4 deletions src/main/kotlin/at/bitfire/dav4jvm/DavCalendar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import java.time.format.DateTimeFormatter
import java.util.Locale
import java.util.logging.Logger

@Suppress("unused")
class DavCalendar @JvmOverloads constructor(
httpClient: OkHttpClient,
location: HttpUrl,
log: Logger = Dav4jvm.log
): DavCollection(httpClient, location, log) {
httpClient: OkHttpClient,
location: HttpUrl,
logger: Logger = Logger.getLogger(DavCalendar::javaClass.name)
): DavCollection(httpClient, location, logger) {

companion object {
val MIME_ICALENDAR = "text/calendar".toMediaType()
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/at/bitfire/dav4jvm/DavCollection.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import at.bitfire.dav4jvm.exception.DavException
import at.bitfire.dav4jvm.exception.HttpException
import at.bitfire.dav4jvm.property.webdav.NS_WEBDAV
import at.bitfire.dav4jvm.property.webdav.SyncToken
import java.io.StringWriter
import java.util.logging.Logger
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.StringWriter
import java.util.logging.Logger

/**
* Represents a WebDAV collection.
*/
open class DavCollection @JvmOverloads constructor(
httpClient: OkHttpClient,
location: HttpUrl,
log: Logger = Dav4jvm.log
): DavResource(httpClient, location, log) {
httpClient: OkHttpClient,
location: HttpUrl,
logger: Logger = Logger.getLogger(DavCollection::class.java.name)
): DavResource(httpClient, location, logger) {

companion object {
val SYNC_COLLECTION = Property.Name(NS_WEBDAV, "sync-collection")
Expand Down
30 changes: 15 additions & 15 deletions src/main/kotlin/at/bitfire/dav4jvm/DavResource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ import at.bitfire.dav4jvm.property.caldav.NS_CALDAV
import at.bitfire.dav4jvm.property.carddav.NS_CARDDAV
import at.bitfire.dav4jvm.property.webdav.NS_WEBDAV
import at.bitfire.dav4jvm.property.webdav.SyncToken
import java.io.EOFException
import java.io.IOException
import java.io.Reader
import java.io.StringWriter
import java.net.HttpURLConnection
import java.util.logging.Level
import java.util.logging.Logger
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType
Expand All @@ -37,6 +30,13 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.EOFException
import java.io.IOException
import java.io.Reader
import java.io.StringWriter
import java.net.HttpURLConnection
import java.util.logging.Level
import java.util.logging.Logger
import at.bitfire.dav4jvm.Response as DavResponse

/**
Expand All @@ -52,12 +52,12 @@ import at.bitfire.dav4jvm.Response as DavResponse
*
* @param httpClient [OkHttpClient] to access this object (must not follow redirects)
* @param location location of the WebDAV resource
* @param log will be used for logging
* @param logger will be used for logging
*/
open class DavResource @JvmOverloads constructor(
val httpClient: OkHttpClient,
location: HttpUrl,
val log: Logger = Dav4jvm.log
val httpClient: OkHttpClient,
location: HttpUrl,
val logger: Logger = Logger.getLogger(DavResource::class.java.name)
) {

companion object {
Expand Down Expand Up @@ -680,7 +680,7 @@ open class DavResource @JvmOverloads constructor(
response.use {
val target = it.header("Location")?.let { location.resolve(it) }
if (target != null) {
log.fine("Redirected, new location = $target")
logger.fine("Redirected, new location = $target")

if (location.isHttps && !target.isHttps)
throw DavException("Received redirect from HTTPS to HTTP")
Expand Down Expand Up @@ -718,18 +718,18 @@ open class DavResource @JvmOverloads constructor(
val firstBytes = ByteArray(XML_SIGNATURE.size)
body.source().peek().readFully(firstBytes)
if (XML_SIGNATURE.contentEquals(firstBytes)) {
Dav4jvm.log.warning("Received 207 Multi-Status that seems to be XML but has MIME type $mimeType")
logger.warning("Received 207 Multi-Status that seems to be XML but has MIME type $mimeType")

// response is OK, return and do not throw Exception below
return
}
} catch (e: Exception) {
Dav4jvm.log.log(Level.WARNING, "Couldn't scan for XML signature", e)
logger.log(Level.WARNING, "Couldn't scan for XML signature", e)
}

throw DavException("Received non-XML 207 Multi-Status", httpResponse = response)
}
} ?: log.warning("Received 207 Multi-Status without Content-Type, assuming XML")
} ?: logger.warning("Received 207 Multi-Status without Content-Type, assuming XML")
}


Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/at/bitfire/dav4jvm/HttpUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
import java.util.Locale
import java.util.logging.Logger

object HttpUtils {

Expand All @@ -24,6 +25,10 @@ object HttpUtils {
private const val httpDateFormatStr = "EEE, dd MMM yyyy HH:mm:ss ZZZZ"
private val httpDateFormat = DateTimeFormatter.ofPattern(httpDateFormatStr, Locale.US)

private val logger
get() = Logger.getLogger(javaClass.name)


/**
* Gets the resource name (the last segment of the path) from an URL.
* Empty if the resource is the base directory.
Expand Down Expand Up @@ -91,7 +96,7 @@ object HttpUtils {
}

// no success in parsing
Dav4jvm.log.warning("Couldn't parse HTTP date: $dateStr, ignoring")
logger.warning("Couldn't parse HTTP date: $dateStr, ignoring")
return null
}

Expand Down
8 changes: 5 additions & 3 deletions src/main/kotlin/at/bitfire/dav4jvm/Property.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

package at.bitfire.dav4jvm

import at.bitfire.dav4jvm.Dav4jvm.log
import at.bitfire.dav4jvm.exception.InvalidPropertyException
import org.xmlpull.v1.XmlPullParser
import java.io.Serializable
import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger

/**
* Represents a WebDAV property.
Expand All @@ -33,6 +33,8 @@ interface Property {
companion object {

fun parse(parser: XmlPullParser): List<Property> {
val logger = Logger.getLogger(Property::javaClass.name)

// <!ELEMENT prop ANY >
val depth = parser.depth
val properties = LinkedList<Property>()
Expand All @@ -50,9 +52,9 @@ interface Property {
if (property != null) {
properties.add(property)
} else
log.fine("Ignoring unknown property $name")
logger.fine("Ignoring unknown property $name")
} catch (e: InvalidPropertyException) {
log.log(Level.WARNING, "Ignoring invalid property", e)
logger.log(Level.WARNING, "Ignoring invalid property", e)
}
}

Expand Down
Loading

0 comments on commit ca363be

Please sign in to comment.