From 03d85a3f558f3680556d83d6f54fe22e5596472a Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sat, 27 Jun 2026 18:29:20 +0200 Subject: [PATCH] add session auth callback --- dav-rs/src/dav/ffi.rs | 5 +++++ dav-rs/src/dav/session.rs | 30 +++++++++++++++++++++++++++++- libidav/atomic.h | 2 +- libidav/session.c | 4 ++++ libidav/webdav.h | 1 + 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/dav-rs/src/dav/ffi.rs b/dav-rs/src/dav/ffi.rs index aea58aa..982296c 100644 --- a/dav-rs/src/dav/ffi.rs +++ b/dav-rs/src/dav/ffi.rs @@ -68,6 +68,11 @@ pub type DavReadFunc = Option libc::size_t>; pub type DavSeekFunc = Option c_int>; + +pub type DavDestructorFunc = Option; + +pub type DavAuthCallback = Option c_int>; + #[repr(C)] #[allow(dead_code)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/dav-rs/src/dav/session.rs b/dav-rs/src/dav/session.rs index b7d4b11..e744746 100644 --- a/dav-rs/src/dav/session.rs +++ b/dav-rs/src/dav/session.rs @@ -27,10 +27,11 @@ */ #![allow(dead_code)] -use std::ffi::{c_char, c_int, CStr, CString}; +use std::ffi::{c_char, c_int, c_void, CStr, CString}; use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign}; use crate::dav::context::DavContext; use crate::dav::ffi; +use crate::dav::ffi::{DavAuthCallback, DavDestructorFunc}; pub struct Session { pub ptr: *mut ffi::DavSession @@ -54,6 +55,10 @@ impl Clone for Session { } } +struct AuthCallbackWrapper { + callback: Box bool>, +} + impl Session { pub fn set_auth(&self, user: &str, password: &str) { let user_cstr = CString::new(user).unwrap(); @@ -72,6 +77,26 @@ impl Session { dav_session_enable_encryption(self.ptr, flags.bits() as i32); } } + + pub fn auth_callback(&self, f: F) + where F: FnMut(&Session) -> bool + 'static { + let wrapper = Box::new( AuthCallbackWrapper { callback: Box::new(f) }); + let raw = Box::into_raw(wrapper); + unsafe { + dav_session_reg_destructor(self.ptr, raw as *mut c_void, Some(auth_callback_destructor)); + dav_session_set_authcallback(self.ptr, Some(auth_callback), raw as *mut c_void); + } + } +} + +extern "C" fn auth_callback(sn: *mut ffi::DavSession, userdata: *mut c_void) -> c_int { + let wrapper: &mut AuthCallbackWrapper = unsafe { &mut *(userdata as *mut AuthCallbackWrapper) }; + (wrapper.callback)(&Session { ptr: sn }) as c_int +} + +extern "C" fn auth_callback_destructor(data: *mut c_void) { + let callback: Box bool> = unsafe { Box::from_raw(data as *mut Box bool>) }; + drop(callback); } @@ -233,9 +258,12 @@ unsafe extern "C" { fn dav_session_unref(sn: *mut ffi::DavSession); fn dav_session_clone(sn: *mut ffi::DavSession) -> *mut ffi::DavSession; fn dav_session_set_auth(sn: *mut ffi::DavSession, user: *const c_char, password: *const c_char); + fn dav_session_set_authcallback(sn: *mut ffi::DavSession, func: DavAuthCallback, userdata: *mut c_void); fn dav_session_get_error(sn: *const ffi::DavSession) -> ffi::DavError; fn dav_session_get_errorstr(sn: *const ffi::DavSession) -> *const c_char; fn dav_session_enable_encryption(sn: *mut ffi::DavSession, flags: c_int); + + fn dav_session_reg_destructor(sn: *mut ffi::DavSession, data: *mut c_void, destructor: DavDestructorFunc); } \ No newline at end of file diff --git a/libidav/atomic.h b/libidav/atomic.h index 8f63d46..44ed050 100644 --- a/libidav/atomic.h +++ b/libidav/atomic.h @@ -33,7 +33,7 @@ extern "C" { #endif -#if defined(__gnu_linux__) || defined(OSX) || defined(BSD) +#if defined(__gnu_linux__) || defined(__APPLE__) || defined(__GNUC__) || defined(__clang__) #define dav_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1) #define dav_atomic_dec32(intptr) (__sync_fetch_and_sub(intptr, 1) - 1) diff --git a/libidav/session.c b/libidav/session.c index 4d1b6c5..9937a04 100644 --- a/libidav/session.c +++ b/libidav/session.c @@ -406,6 +406,10 @@ char* dav_session_strdup(DavSession *sn, const char *str) { return cx_strdup_a(sn->mp->allocator, cx_str((char*)str)).ptr; } +void dav_session_reg_destructor(DavSession *sn, void *data, cx_destructor_func destr) { + cxMempoolRegister(sn->mp, data, destr); +} + char* dav_session_create_plain_href(DavSession *sn, const char *path) { if(!DAV_ENCRYPT_NAME(sn) && !DAV_DECRYPT_NAME(sn)) { diff --git a/libidav/webdav.h b/libidav/webdav.h index 14f4160..c5526d8 100644 --- a/libidav/webdav.h +++ b/libidav/webdav.h @@ -317,6 +317,7 @@ void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size); void* dav_session_realloc(DavSession *sn, void *ptr, size_t size); void dav_session_free(DavSession *sn, void *ptr); char* dav_session_strdup(DavSession *sn, const char *str); +void dav_session_reg_destructor(DavSession *sn, void *data, cx_destructor_func destr); void dav_set_effective_href(DavSession *sn, DavResource *resource); DavResource* dav_get(DavSession *sn, char *path, const char *properties); -- 2.52.0