@L-B said in DAVx5-ose (F-Droid) 3.0 doesn't start:
Thank you very much for your work, support and effort!!!
Yep. Thanks a lot guys!! Happy with the update!
I’ve a Radicale3 server serving up contacts/calendars.
It sits behind an nginx reverse-proxy front end; auth to Radicale is provided by passthrough basic auth.
With the following nginx config – with NO ssl client cert verification – DavX5 connects without issue:
server {
listen 10.0.1.20:10000 ssl http2;
server_name front.example.com;
root /dev/null;
autoindex off;
ssl_verify_client off;
ssl_verify_depth 2;
ssl_client_certificate "/srv/ssl/myCA_CHAIN.crt";
ssl_certificate "/srv/ssl/front.server.EC.crt";
ssl_certificate_key "/srv/ssl/front.server.EC.key";
location / {
root /srv/nulldir;
allow 10.0.1.100;
deny all;
try_files $uri $uri/ =404;
}
location /dav/ {
proxy_pass https://radicale.example.com:20000/;
proxy_ssl_name radicale.example.com;
proxy_set_header X-Script-Name /dav;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_certificate "/srv/ssl/radicale.client.EC.crt";
proxy_ssl_certificate_key "/srv/ssl/radicale.client.EC.key";
proxy_ssl_trusted_certificate "/srv/ssl/myCA_CHAIN.crt";
auth_basic "DAV - Password Required";
auth_basic_user_file /srv/auth/radicale.auth;
include includes/reverse-proxy.inc;
}
however,
if I require ssl client verification,
- ssl_verify_client off;
+ ssl_verify_client on;
ensuring a valid cert on the phone, connection fails, apparently because DavX5 fails to send an SSL cert; debug logs follow.
what additional config/settings are required for DavX5 to correctly serve-up the client-side cert for verification @ the server?
--- BEGIN DEBUG INFO ---
SYNCHRONIZATION INFO
Account: Account {name=Card.001 (testuser@example.com Ug), type=at.bitfire.davdroid.address_book}
Authority: com.android.contacts
EXCEPTION
at.bitfire.dav4jvm.exception.HttpException: HTTP 400
at at.bitfire.dav4jvm.DavResource.checkStatus(DavResource.kt:6)
at at.bitfire.dav4jvm.DavResource.checkStatus(DavResource.kt:3)
at at.bitfire.dav4jvm.DavResource.processMultiStatus(DavResource.kt:1)
at at.bitfire.dav4jvm.DavResource.propfind(DavResource.kt:11)
at at.bitfire.davdroid.syncadapter.ContactsSyncManager$queryCapabilities$1.invoke(ContactsSyncManager.kt:3)
at at.bitfire.davdroid.syncadapter.ContactsSyncManager$queryCapabilities$1.invoke(ContactsSyncManager.kt:1)
at at.bitfire.davdroid.syncadapter.SyncManager.remoteExceptionContext(SyncManager.kt:1)
at at.bitfire.davdroid.syncadapter.SyncManager.remoteExceptionContext(SyncManager.kt:9)
at at.bitfire.davdroid.syncadapter.ContactsSyncManager.queryCapabilities(ContactsSyncManager.kt:3)
at at.bitfire.davdroid.syncadapter.SyncManager$performSync$1.invoke(SyncManager.kt:6)
at at.bitfire.davdroid.syncadapter.SyncManager$performSync$1.invoke(SyncManager.kt:1)
at at.bitfire.davdroid.syncadapter.SyncManager.unwrapExceptions(SyncManager.kt:1)
at at.bitfire.davdroid.syncadapter.SyncManager.performSync(SyncManager.kt:5)
at at.bitfire.davdroid.syncadapter.ContactsSyncAdapterService$ContactsSyncAdapter.sync(ContactsSyncAdapterService.kt:15)
at at.bitfire.davdroid.syncadapter.SyncAdapterService$SyncAdapter.onPerformSync(SyncAdapterService.kt:17)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:334)
HTTP REQUEST
Request{method=PROPFIND, url=https://front.example.com:10000/dav/testuser%40example.com/33333333-3333-3333-3333-333333333333/, headers=[Depth:0, Accept-Encoding:br,gzip]}
<?xml version='1.0' encoding='UTF-8' ?><propfind xmlns="DAV:" xmlns:CAL="urn:ietf:params:xml:ns:caldav" xmlns:CARD="urn:ietf:params:xml:ns:carddav"><prop><CARD:supported-address-data /><supported-report-set /><n0:getctag xmlns:n0="http://calendarserver.org/ns/" /><sync-token /></prop></propfind>
HTTP RESPONSEResponse{protocol=h2, code=400, message=, url=https://front.example.com:10000/dav/testuser%40example.com/33333333-3333-3333-3333-333333333333/}
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx</center>
</body>
</html>
REMOTE RESOURCE
https://front.example.com:10000/dav/testuser%40example.com/33333333-3333-3333-3333-333333333333/
SOFTWARE INFORMATION
┌────────────────────────────────┬─────────────┬───────────┬─────────────────────┬───────┐
│ Package │ Version │ Code │ Installer │ Notes │
├────────────────────────────────┼─────────────┼───────────┼─────────────────────┼───────┤
│ at.bitfire.davdroid │ 3.3.1-gplay │ 303010001 │ com.android.vending │ │
│ org.dmfs.tasks │ 1.2.3 │ 77600 │ com.android.vending │ │
│ com.android.providers.contacts │ 10 │ 29 │ — │ │
│ com.android.providers.calendar │ 10 │ 29 │ — │ │
│ com.android.contacts │ 1.7.31 │ 10731 │ — │ │
│ com.dw.contacts │ 3.1.7.5 │ 3175 │ com.android.vending │ │
│ org.lineageos.etar │ 10 │ 29 │ — │ │
│ com.aboutmycode.betteropenwith │ 1.4.11 │ 53 │ com.android.vending │ │
│ com.appgenix.bizcal │ 2.40.4 │ 240403 │ com.android.vending │ │
└────────────────────────────────┴─────────────┴───────────┴─────────────────────┴───────┘
SYSTEM INFORMATION
Android version: 10 (lineage_star2lte-userdebug 10 QQ3A.200605.001 eng.rob.20200712.181146 test-keys)
Device: samsung SM-G965F (star2lte)
CONNECTVITY
☒ [ Transports: CELLULAR Capabilities: MMS SUPL IA INTERNET NOT_RESTRICTED TRUSTED NOT_VPN VALIDATED NOT_ROAMING FOREGROUND NOT_CONGESTED NOT_SUSPENDED LinkUpBandwidth>=15000Kbps LinkDnBandwidth>=30000Kbps Specifier: <1>]
Data saver: disabled
CONFIGURATION
Power saving disabled: yes
System-wide synchronization: automatically
Notifications:
- sync isBlocked=false
* syncProblems: importance=2
* syncIoErrors: importance=1
* syncWarnings: importance=2
- cert4android: importance=2
- general: importance=2
- debug: importance=0
Permissions:
- READ_CONTACTS: granted
- WRITE_CONTACTS: granted
- READ_CALENDAR: granted
- WRITE_CALENDAR: granted
- READ_TASKS: granted
- WRITE_TASKS: granted
- ACCESS_COARSE_LOCATION: denied
ACCOUNTS
- Account: shared@example.com
┌──────────────────────────────────┬────────────┬──────────────────────┬───────────────┐
│ Authority │ isSyncable │ getSyncAutomatically │ Sync interval │
├──────────────────────────────────┼────────────┼──────────────────────┼───────────────┤
│ at.bitfire.davdroid.addressbooks │ 1 │ true │ 60 min │
│ com.android.calendar │ 1 │ true │ 60 min │
│ com.android.contacts │ 0 │ false │ — │
│ org.dmfs.tasks │ 1 │ true │ 60 min │
└──────────────────────────────────┴────────────┴──────────────────────┴───────────────┘
WiFi only: false
Contact group method: CATEGORIES
Time range (past days): null
Default alarm (min before): null
Manage calendar colors: true
Use event colors: true
* Address book: Card.Shared (shared@example.com eg)
┌────────────┬──────────────────────┬───────────────┐
│ isSyncable │ getSyncAutomatically │ Sync interval │
├────────────┼──────────────────────┼───────────────┤
│ 1 │ true │ 1440 min │
└────────────┴──────────────────────┴───────────────┘
URL: https://front.example.com:10000/dav/shared%40example.com/22222222-2222-2222-2222-222222222222/
Read-only: 0
- Account: testuser@example.com
┌──────────────────────────────────┬────────────┬──────────────────────┬───────────────┐
│ Authority │ isSyncable │ getSyncAutomatically │ Sync interval │
├──────────────────────────────────┼────────────┼──────────────────────┼───────────────┤
│ at.bitfire.davdroid.addressbooks │ 1 │ true │ 60 min │
│ com.android.calendar │ 1 │ true │ 60 min │
│ com.android.contacts │ 0 │ false │ — │
│ org.dmfs.tasks │ 1 │ true │ 60 min │
└──────────────────────────────────┴────────────┴──────────────────────┴───────────────┘
WiFi only: false
Contact group method: CATEGORIES
Time range (past days): null
Default alarm (min before): null
Manage calendar colors: true
Use event colors: true
* Address book: Card.001 (testuser@example.com Ug)
┌────────────┬──────────────────────┬───────────────┐
│ isSyncable │ getSyncAutomatically │ Sync interval │
├────────────┼──────────────────────┼───────────────┤
│ 1 │ true │ — │
└────────────┴──────────────────────┴───────────────┘
URL: https://front.example.com:10000/dav/testuser%40example.com/33333333-3333-3333-3333-333333333333/
Read-only: 0
DATABASE DUMP
android_metadata
┌────────┐
│ locale │
├────────┤
│ en_US │
└────────┘
service
┌────┬────────────────────────────┬─────────┬───────────────────────────────────────────────────────────────────────────────┐
│ id │ accountName │ type │ principal │
├────┼────────────────────────────┼─────────┼───────────────────────────────────────────────────────────────────────────────┤
│ 7 │ shared@example.com │ carddav │ https://front.example.com:10000/dav/shared%40example.com/ │
│ 8 │ shared@example.com │ caldav │ https://front.example.com:10000/dav/shared%40example.com/ │
│ 9 │ testuser@example.com │ carddav │ https://front.example.com:10000/dav/testuser%40example.com/ │
│ 10 │ testuser@example.com │ caldav │ https://front.example.com:10000/dav/testuser%40example.com/ │
└────┴────────────────────────────┴─────────┴───────────────────────────────────────────────────────────────────────────────┘
sqlite_sequence
┌────────────┬─────┐
│ name │ seq │
├────────────┼─────┤
│ service │ 10 │
│ collection │ 10 │
│ homeset │ 10 │
└────────────┴─────┘
homeset
┌────┬───────────┬───────────────────────────────────────────────────────────────────────────────┬──────────┬─────────────┐
│ id │ serviceId │ url │ privBind │ displayName │
├────┼───────────┼───────────────────────────────────────────────────────────────────────────────┼──────────┼─────────────┤
│ 7 │ 8 │ https://front.example.com:10000/dav/shared%40example.com/ │ 1 │ — │
│ 8 │ 7 │ https://front.example.com:10000/dav/shared%40example.com/ │ 1 │ — │
│ 9 │ 9 │ https://front.example.com:10000/dav/testuser%40example.com/ │ 1 │ — │
│ 10 │ 10 │ https://front.example.com:10000/dav/testuser%40example.com/ │ 1 │ — │
└────┴───────────┴───────────────────────────────────────────────────────────────────────────────┴──────────┴─────────────┘
collection
┌────┬───────────┬──────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────┬────────────┬───────────────┬─────────────────┬─────────────────┬───────────┬──────────┬────────────────┬───────────────┬──────────────────┬────────┬──────┐
│ id │ serviceId │ type │ url │ privWriteContent │ privUnbind │ forceReadOnly │ displayName │ description │ color │ timezone │ supportsVEVENT │ supportsVTODO │ supportsVJOURNAL │ source │ sync │
├────┼───────────┼──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────┼────────────┼───────────────┼─────────────────┼─────────────────┼───────────┼──────────┼────────────────┼───────────────┼──────────────────┼────────┼──────┤
│ 7 │ 8 │ CALENDAR │ https://front.example.com:10000/dav/shared%40example.com/11111111-1111-1111-1111-111111111111/ │ 1 │ 1 │ 0 │ Cal.Shared │ Cal.Shared │ -7021909 │ — │ 1 │ 1 │ 1 │ — │ 1 │
│ 8 │ 7 │ ADDRESS_BOOK │ https://front.example.com:10000/dav/shared%40example.com/22222222-2222-2222-2222-222222222222/ │ 1 │ 1 │ 0 │ Card.Shared │ Card.Shared │ — │ — │ — │ — │ — │ — │ 1 │
│ 9 │ 9 │ ADDRESS_BOOK │ https://front.example.com:10000/dav/testuser%40example.com/33333333-3333-3333-3333-333333333333/ │ 1 │ 1 │ 0 │ Card.001 │ Card.001 │ — │ — │ — │ — │ — │ — │ 1 │
│ 10 │ 10 │ CALENDAR │ https://front.example.com:10000/dav/testuser%40example.com/44444444-4444-4444-4444-444444444444/ │ 1 │ 1 │ 0 │ Cal.001 │ Cal.001 │ -10782310 │ — │ 1 │ 1 │ 1 │ — │ 1 │
└────┴───────────┴──────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────┴────────────┴───────────────┴─────────────────┴─────────────────┴───────────┴──────────┴────────────────┴───────────────┴──────────────────┴────────┴──────┘
room_master_table
┌────┬──────────────────────────────────┐
│ id │ identity_hash │
├────┼──────────────────────────────────┤
│ 42 │ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │
└────┴──────────────────────────────────┘
APP SETTINGS
1. SharedPreferencesProvider canWrite=true
┌───────────────────────────┬───────────┐
│ Setting │ Value │
├───────────────────────────┼───────────┤
│ distrust_system_certs │ false │
│ hint_AutostartPermissions │ false │
│ log_to_file │ true │
│ override_proxy │ false │
│ override_proxy_host │ localhost │
│ override_proxy_port │ 8118 │
└───────────────────────────┴───────────┘
2. DefaultsProvider canWrite=false
┌───────────────────────┬───────────┐
│ Setting │ Value │
├───────────────────────┼───────────┤
│ distrust_system_certs │ false │
│ override_proxy │ false │
│ override_proxy_host │ localhost │
│ override_proxy_port │ 8118 │
└───────────────────────┴───────────┘
--- END DEBUG INFO ---
Hi,
Did you choose “Login with URL and client certificate” when creating the DAVx5 account?
I’d attempted that …
However, in that config it no longer passes the password required for Radicale login.
I need both: access control with cert to the Nginx front-end, and auth control with user:pass to the Radicale back-end.
@pgnd This is currently not possible with DAVx5, because there is no UI for that. See https://gitlab.com/bitfireAT/davx5-ose/-/wikis/Roadmap “login”
so it is either-or, not both at the moment.
that feature will be useful – and necessary for several new/planned organization-wide implementations. here, anyway.
is that feature tagged to a milestone? with any associated timeframe?
@pgnd said in DAVx5 fails to send server-required SSL cert: "400 No required SSL certificate was sent" ?:
so it is either-or, not both at the moment.
Yes.
that feature will be useful – and necessary for several new/planned organization-wide implementations. here, anyway.
I see. What is the use case? We have implemented client-side certificate for an organization, too. What is the user name/password needed for? Isn’t the client certificate used to identify the client?
is that feature tagged to a milestone? with any associated timeframe?
No, unfortunately not. There are so many other things at the moment.
There’s also already a merge request for that: https://gitlab.com/bitfireAT/davx5-ose/-/merge_requests/13 (as you can see, it’s only an UI thing; because the engine can already do Basic and client certificates)
But there are some unresolved UI implications yet, and UI is always complicated.
What is the use case? We have implemented client-side certificate for an organization, too. What is the user name/password needed for? Isn’t the client certificate used to identify the client?
the nginx front-end reverse-proxies many backend apps.
the client cert provides access control for access to the front-end.
auth to the backend apps is provided by their respective, individual auth mechanisms. typically username + strong-pass.
that’ll eventually be additionally wrapped in an SSO portal that’ll add 2FA.
No, unfortunately not. There are so many other things at the moment.
understood.
as much as I personally like the davx5 client functionality/stability, it seems like this may not be the solution that fits for broader use here.