diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b9fc85..533883e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,11 @@ install(FILES include/wsfs/status.h DESTINATION include/wsfs) set(WSFS_ADAPTER_SOURCES lib/wsfs/adapter/filesystem.c lib/wsfs/adapter/server.c + lib/wsfs/adapter/server_config.c + lib/wsfs/adapter/server_protocol.c + lib/wsfs/adapter/authenticator.c + lib/wsfs/adapter/authenticators.c + lib/wsfs/adapter/credentials.c lib/wsfs/adapter/time/timepoint.c lib/wsfs/adapter/time/timer.c lib/wsfs/adapter/time/timeout_manager.c @@ -67,8 +72,6 @@ set(WSFS_ADAPTER_SOURCES lib/wsfs/adapter/operation/open.c lib/wsfs/adapter/operation/close.c lib/wsfs/adapter/operation/read.c - lib/wsfs/adapter/server_config.c - lib/wsfs/adapter/server_protocol.c lib/wsfs/adapter/jsonrpc/server.c lib/wsfs/adapter/jsonrpc/method.c lib/wsfs/adapter/jsonrpc/request.c diff --git a/include/wsfs/adapter/authenticate.h b/include/wsfs/adapter/authenticate.h new file mode 100644 index 0000000..9e630ee --- /dev/null +++ b/include/wsfs/adapter/authenticate.h @@ -0,0 +1,15 @@ +#ifndef WSFS_ADAPTER_AUTHENTICATE_H +#define WSFS_ADAPTER_AUTHENTICATE_H + +#ifndef __cplusplus +#include +#endif + +struct wsfs_credentials; + +typedef bool wsfs_authenticate_fn( + struct wsfs_credentials * credentials, + void * user_data); + + +#endif diff --git a/include/wsfs/adapter/credentials.h b/include/wsfs/adapter/credentials.h new file mode 100644 index 0000000..747b107 --- /dev/null +++ b/include/wsfs/adapter/credentials.h @@ -0,0 +1,25 @@ +#ifndef WSFS_ADAPTER_CREDENTIALS_H +#define WSFS_ADAPTER_CREDENTIALS_H + +#include "wsfs/adapter/api.h" + +struct wsfs_credentials; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern WSFSA_API char const * wsfs_credentials_type( + struct wsfs_credentials const * credentials); + +extern WSFSA_API char const * wsfs_credentials_get( + struct wsfs_credentials const * credentials, + char const * key); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/wsfs/adapter/server_config.h b/include/wsfs/adapter/server_config.h index b6d9b7e..df4966e 100644 --- a/include/wsfs/adapter/server_config.h +++ b/include/wsfs/adapter/server_config.h @@ -2,6 +2,7 @@ #define WSFS_ADAPTER_SERVER_CONFIG_H #include "wsfs/adapter/api.h" +#include "wsfs/adapter/authenticate.h" struct wsfs_server_config; @@ -40,6 +41,13 @@ extern WSFSA_API void wsfs_server_config_set_port( struct wsfs_server_config * config, int port); +extern WSFSA_API void wsfs_server_add_authenticator( + struct wsfs_server_config * config, + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data +); + #ifdef __cplusplus } #endif diff --git a/include/wsfs_adapter.h b/include/wsfs_adapter.h index 6a812a3..6900f13 100644 --- a/include/wsfs_adapter.h +++ b/include/wsfs_adapter.h @@ -7,5 +7,7 @@ #include #include #include +#include +#include #endif diff --git a/lib/wsfs/adapter/authenticator.c b/lib/wsfs/adapter/authenticator.c new file mode 100644 index 0000000..04f1c60 --- /dev/null +++ b/lib/wsfs/adapter/authenticator.c @@ -0,0 +1,49 @@ +#include "wsfs/adapter/authenticator.h" + +#include +#include + +#include "wsfs/adapter/credentials_intern.h" + +struct wsfs_authenticator * wsfs_authenticator_create( + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data) +{ + struct wsfs_authenticator * authenticator = malloc(sizeof(struct wsfs_authenticator)); + if (NULL != authenticator) + { + authenticator->type = strdup(type); + authenticator->authenticate = authenticate; + authenticator->user_data = user_data; + authenticator->next = NULL; + } + + return authenticator; +} + +void wsfs_authenticator_dispose( + struct wsfs_authenticator * authenticator) +{ + free(authenticator->type); + free(authenticator); +} + +bool wsfs_authenticator_autenticate( + struct wsfs_authenticator * authenticator, + struct wsfs_credentials * credentials) +{ + bool result; + + if (0 == strcmp(authenticator->type, credentials->type)) + { + result = authenticator->authenticate(credentials, authenticator->user_data); + } + else + { + result = false; + } + + + return result; +} \ No newline at end of file diff --git a/lib/wsfs/adapter/authenticator.h b/lib/wsfs/adapter/authenticator.h new file mode 100644 index 0000000..585cc24 --- /dev/null +++ b/lib/wsfs/adapter/authenticator.h @@ -0,0 +1,40 @@ +#ifndef WSFS_ADAPTER_AUTHENTICATOR_H +#define WSFS_ADAPTER_AUTHENTICATOR_H + +#ifndef __cplusplus +#include +#endif + +#include "wsfs/adapter/authenticate.h" + +struct wsfs_authenticator +{ + char * type; + wsfs_authenticate_fn * authenticate; + void * user_data; + struct wsfs_authenticator * next; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern struct wsfs_authenticator * wsfs_authenticator_create( + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data); + +extern void wsfs_authenticator_dispose( + struct wsfs_authenticator * authenticator); + +extern bool wsfs_authenticator_autenticate( + struct wsfs_authenticator * authenticator, + struct wsfs_credentials * credentials); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/lib/wsfs/adapter/authenticators.c b/lib/wsfs/adapter/authenticators.c new file mode 100644 index 0000000..aa59809 --- /dev/null +++ b/lib/wsfs/adapter/authenticators.c @@ -0,0 +1,101 @@ +#include "wsfs/adapter/authenticators.h" +#include +#include + +#include "wsfs/adapter/authenticator.h" +#include "wsfs/adapter/credentials_intern.h" + +static struct wsfs_authenticator * wsfs_authenticators_find( + struct wsfs_authenticators * authenticators, + char const * type) +{ + struct wsfs_authenticator * result = NULL; + + struct wsfs_authenticator * actual = authenticators->first; + while ((NULL == result) && (NULL != actual)) + { + struct wsfs_authenticator * next = actual->next; + if (0 == strcmp(type, actual->type)) + { + result = actual; + } + + actual = next; + } + + return result; +} + +void wsfs_authenticators_init( + struct wsfs_authenticators * authenticators) +{ + authenticators->first = NULL; +} + +void wsfs_authenticators_cleanup( + struct wsfs_authenticators * authenticators) +{ + struct wsfs_authenticator * actual = authenticators->first; + while (NULL != actual) + { + struct wsfs_authenticator * next = actual->next; + wsfs_authenticator_dispose(actual); + actual = next; + } + + authenticators->first = NULL; +} + +void wsfs_authenticators_clone( + struct wsfs_authenticators * authenticators, + struct wsfs_authenticators * other) +{ + wsfs_authenticators_init(other); + + struct wsfs_authenticator * actual = authenticators->first; + while (NULL != actual) + { + struct wsfs_authenticator * next = actual->next; + wsfs_authenticators_add(other, + actual->type, actual->authenticate, actual->user_data); + actual = next; + } + +} + +void wsfs_authenticators_add( + struct wsfs_authenticators * authenticators, + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data) +{ + struct wsfs_authenticator * authenticator = wsfs_authenticator_create(type, authenticate, user_data); + authenticator->next = authenticators->first; + authenticators->first = authenticator; +} + +bool wsfs_authenticators_authenticate( + struct wsfs_authenticators * authenticators, + struct wsfs_credentials * credentials) +{ + bool result; + + if (NULL != credentials) + { + struct wsfs_authenticator * authenticator = wsfs_authenticators_find(authenticators, credentials->type); + if (NULL != authenticator) + { + result = wsfs_authenticator_autenticate(authenticator, credentials); + } + else + { + result = false; + } + } + else + { + result = (NULL == authenticators->first); + } + + return result; +} \ No newline at end of file diff --git a/lib/wsfs/adapter/authenticators.h b/lib/wsfs/adapter/authenticators.h new file mode 100644 index 0000000..c7cadf6 --- /dev/null +++ b/lib/wsfs/adapter/authenticators.h @@ -0,0 +1,38 @@ +#ifndef WSFS_ADAPTER_AUTHENTICATORS_H +#define WSFS_ADAPTER_AUTHENTICATORS_H + +#ifndef __cplusplus +#include +#endif + +#include "wsfs/adapter/authenticate.h" + +struct wsfs_authenticator; +struct wsfs_credentials; + +struct wsfs_authenticators +{ + struct wsfs_authenticator * first; +}; + +extern void wsfs_authenticators_init( + struct wsfs_authenticators * authenticators); + +extern void wsfs_authenticators_cleanup( + struct wsfs_authenticators * authenticators); + +extern void wsfs_authenticators_clone( + struct wsfs_authenticators * authenticators, + struct wsfs_authenticators * other); + +extern void wsfs_authenticators_add( + struct wsfs_authenticators * authenticators, + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data); + +extern bool wsfs_authenticators_authenticate( + struct wsfs_authenticators * authenticators, + struct wsfs_credentials * credentials); + +#endif diff --git a/lib/wsfs/adapter/credentials.c b/lib/wsfs/adapter/credentials.c new file mode 100644 index 0000000..40df93f --- /dev/null +++ b/lib/wsfs/adapter/credentials.c @@ -0,0 +1,40 @@ +#include "wsfs/adapter/credentials_intern.h" +#include + +void wsfs_credentials_init( + struct wsfs_credentials * credentials, + char const * type, + json_t * data) +{ + credentials->type = strdup(type); + credentials->data = data; + json_incref(credentials->data); +} + +void wsfs_credentails_cleanup( + struct wsfs_credentials * credentials) +{ + free(credentials->type); + json_decref(credentials->data); +} + +char const * wsfs_credentials_type( + struct wsfs_credentials const * credentials) +{ + return credentials->type; +} + +char const * wsfs_credentials_get( + struct wsfs_credentials const * credentials, + char const * key) +{ + char const * result = NULL; + + json_t * value_holder = json_object_get(credentials->data, key); + if (json_is_string(value_holder)) + { + result = json_string_value(value_holder); + } + + return result; +} diff --git a/lib/wsfs/adapter/credentials_intern.h b/lib/wsfs/adapter/credentials_intern.h new file mode 100644 index 0000000..d0c6f44 --- /dev/null +++ b/lib/wsfs/adapter/credentials_intern.h @@ -0,0 +1,30 @@ +#ifndef WSFS_ADAPTER_CREDENTIALS_INTERN_H +#define WSFS_ADAPTER_CREDENTIALS_INTERN_H + +#include "wsfs/adapter/credentials.h" +#include + +struct wsfs_credentials +{ + char * type; + json_t * data; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void wsfs_credentials_init( + struct wsfs_credentials * credentials, + char const * type, + json_t * data); + +extern void wsfs_credentails_cleanup( + struct wsfs_credentials * credentials); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/lib/wsfs/adapter/server_config.c b/lib/wsfs/adapter/server_config.c index 13e1f37..d4602bd 100644 --- a/lib/wsfs/adapter/server_config.c +++ b/lib/wsfs/adapter/server_config.c @@ -18,11 +18,15 @@ void wsfs_server_config_init( struct wsfs_server_config * config) { memset(config, 0, sizeof(struct wsfs_server_config)); + + wsfs_authenticators_init(&config->authenticators); } void wsfs_server_config_cleanup( struct wsfs_server_config * config) { + wsfs_authenticators_cleanup(&config->authenticators); + free(config->mount_point); free(config->document_root); free(config->key_path); @@ -42,6 +46,8 @@ void wsfs_server_config_clone( clone->cert_path = wsfs_server_config_strdup(config->cert_path); clone->vhost_name = wsfs_server_config_strdup(config->vhost_name); clone->port = config->port; + + wsfs_authenticators_clone(&config->authenticators, &clone->authenticators); } struct wsfs_server_config * wsfs_server_config_create(void) @@ -108,3 +114,13 @@ void wsfs_server_config_set_port( { config->port = port; } + +void wsfs_server_add_authenticator( + struct wsfs_server_config * config, + char const * type, + wsfs_authenticate_fn * authenticate, + void * user_data +) +{ + wsfs_authenticators_add(&config->authenticators, type, authenticate, user_data); +} \ No newline at end of file diff --git a/lib/wsfs/adapter/server_config_intern.h b/lib/wsfs/adapter/server_config_intern.h index 941ac8a..2ae0a2f 100644 --- a/lib/wsfs/adapter/server_config_intern.h +++ b/lib/wsfs/adapter/server_config_intern.h @@ -2,6 +2,7 @@ #define WSFS_ADAPTER_SERVER_CONFIG_INTERN_H #include "wsfs/adapter/server_config.h" +#include "wsfs/adapter/authenticators.h" struct wsfs_server_config { @@ -11,6 +12,7 @@ struct wsfs_server_config char * cert_path; char * vhost_name; int port; + struct wsfs_authenticators authenticators; }; #ifdef __cplusplus diff --git a/lib/wsfs/provider/operation/getattr.c b/lib/wsfs/provider/operation/getattr.c index c4be838..90aefa0 100644 --- a/lib/wsfs/provider/operation/getattr.c +++ b/lib/wsfs/provider/operation/getattr.c @@ -32,7 +32,7 @@ void wsfsp_getattr_default( ino_t WSFS_UNUSED_PARAM(inode), void * WSFS_UNUSED_PARAM(user_data)) { - wsfsp_respond_error(request, -1); + wsfsp_respond_error(request, WSFS_BAD_NOENTRY); } void wsfsp_respond_getattr(