From 99e538670dd4349e37884638e2d66cd4152380dc Mon Sep 17 00:00:00 2001 From: Elizabeth Myers Date: Thu, 10 Mar 2016 03:02:16 -0600 Subject: [PATCH] authd: convert auth stuff to use a linked list. This allows runtime loadable providers. --- authd/auth.c | 91 ++++++++++++++++++++++++++++++---------------------- authd/auth.h | 6 ++-- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/authd/auth.c b/authd/auth.c index b65da845..fe7cb9ee 100644 --- a/authd/auth.c +++ b/authd/auth.c @@ -45,32 +45,35 @@ #include "authd.h" #include "auth.h" -#define NULL_PROVIDER { \ - .provider = PROVIDER_NULL, \ - .init = NULL, \ - .destroy = NULL, \ - .start = NULL, \ - .cancel = NULL, \ - .completed = NULL, \ -} - -/* Providers */ -static struct auth_provider auth_providers[] = -{ - NULL_PROVIDER, -}; +rb_dlink_list auth_providers; /* Clients waiting */ struct auth_client auth_clients[MAX_CLIENTS]; +/* Load a provider */ +void load_provider(struct auth_provider *provider) +{ + provider->init(); + rb_dlinkAdd(provider, &provider->node, &auth_providers); +} + +void unload_provider(struct auth_provider *provider) +{ + provider->destroy(); + rb_dlinkDelete(&provider->node, &auth_providers); +} + /* Initalise all providers */ void init_providers(void) { - struct auth_provider *pptr; + rb_dlink_node *ptr; + struct auth_provider *provider; - AUTH_PROVIDER_FOREACH(pptr) + RB_DLINK_FOREACH(ptr, auth_providers.head) { - if(pptr->init && !pptr->init()) + provider = ptr->data; + + if(provider->init && !provider->init()) /* Provider failed to init, time to go */ exit(1); } @@ -79,7 +82,8 @@ void init_providers(void) /* Terminate all providers */ void destroy_providers(void) { - struct auth_provider *pptr; + rb_dlink_node *ptr; + struct auth_provider *provider; /* Cancel outstanding connections */ for (size_t i = 0; i < MAX_CLIENTS; i++) @@ -93,32 +97,38 @@ void destroy_providers(void) } } - AUTH_PROVIDER_FOREACH(pptr) + RB_DLINK_FOREACH(ptr, auth_providers.head) { - if(pptr->destroy) - pptr->destroy(); + provider = ptr->data; + + if(provider->destroy) + provider->destroy(); } } /* Cancel outstanding providers for a client */ void cancel_providers(struct auth_client *auth) { - struct auth_provider *pptr; + rb_dlink_node *ptr; + struct auth_provider *provider; - AUTH_PROVIDER_FOREACH(pptr) + RB_DLINK_FOREACH(ptr, auth_providers.head) { - if(pptr->cancel && is_provider(auth, pptr->provider)) + provider = ptr->data; + + if(provider->cancel && is_provider(auth, provider->id)) /* Cancel if required */ - pptr->cancel(auth); + provider->cancel(auth); } } /* Provider is done */ -void provider_done(struct auth_client *auth, provider_t provider) +void provider_done(struct auth_client *auth, provider_t id) { - struct auth_provider *pptr; + rb_dlink_node *ptr; + struct auth_provider *provider; - unset_provider(auth, provider); + unset_provider(auth, id); if(!auth->providers) { @@ -127,22 +137,24 @@ void provider_done(struct auth_client *auth, provider_t provider) return; } - AUTH_PROVIDER_FOREACH(pptr) + RB_DLINK_FOREACH(ptr, auth_providers.head) { - if(pptr->completed && is_provider(auth, pptr->provider)) + provider = ptr->data; + + if(provider->completed && is_provider(auth, provider->id)) /* Notify pending clients who asked for it */ - pptr->completed(auth, provider); + provider->completed(auth, id); } } /* Reject a client, cancel outstanding providers if any */ -void reject_client(struct auth_client *auth, provider_t provider, const char *reason) +void reject_client(struct auth_client *auth, provider_t id, const char *reason) { uint16_t cid = auth->cid; rb_helper_write(authd_helper, "R %x :%s", auth->cid, reason); - unset_provider(auth, provider); + unset_provider(auth, id); if(auth->providers) cancel_providers(auth); @@ -151,13 +163,13 @@ void reject_client(struct auth_client *auth, provider_t provider, const char *re } /* Accept a client, cancel outstanding providers if any */ -void accept_client(struct auth_client *auth, provider_t provider) +void accept_client(struct auth_client *auth, provider_t id) { uint16_t cid = auth->cid; rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname); - unset_provider(auth, provider); + unset_provider(auth, id); if(auth->providers) cancel_providers(auth); @@ -174,7 +186,8 @@ void notice_client(struct auth_client *auth, const char *notice) /* Begin authenticating user */ void start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_ip, const char *c_port) { - struct auth_provider *pptr; + rb_dlink_node *ptr; + struct auth_provider *provider; struct auth_client *auth; long lcid = strtol(cid, NULL, 16); @@ -194,10 +207,12 @@ void start_auth(const char *cid, const char *l_ip, const char *l_port, const cha rb_strlcpy(auth->c_ip, c_ip, sizeof(auth->c_ip)); auth->c_port = (uint16_t)atoi(c_port); - AUTH_PROVIDER_FOREACH(pptr) + RB_DLINK_FOREACH(ptr, auth_providers.head) { + provider = ptr->data; + /* Execute providers */ - if(!pptr->start(auth)) + if(!provider->start(auth)) { /* Rejected immediately */ cancel_providers(auth); diff --git a/authd/auth.h b/authd/auth.h index f7cf8b43..c5a481f2 100644 --- a/authd/auth.h +++ b/authd/auth.h @@ -60,7 +60,9 @@ typedef void (*provider_destroy_t)(void); struct auth_provider { - provider_t provider; + rb_dlink_node node; + + provider_t id; provider_init_t init; /* Initalise the provider */ provider_destroy_t destroy; /* Terminate the provider */ @@ -70,8 +72,6 @@ struct auth_provider provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */ }; -#define AUTH_PROVIDER_FOREACH(a) for((a) = auth_providers; (a)->provider; (a)++) - void init_providers(void); void destroy_providers(void); void cancel_providers(struct auth_client *auth);