mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 08:24:08 +01:00
Revert "authd: change to lists instead of dictionaries for various things"
This reverts commit 49fd293f20
.
This commit is contained in:
parent
92404a1a98
commit
a71b65b15c
6 changed files with 75 additions and 112 deletions
106
authd/provider.c
106
authd/provider.c
|
@ -47,56 +47,26 @@
|
|||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "rb_lib.h"
|
||||
#include "rb_dictionary.h"
|
||||
#include "authd.h"
|
||||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
|
||||
static EVH provider_timeout_event;
|
||||
|
||||
rb_dlink_list auth_clients;
|
||||
rb_dlink_list auth_providers;
|
||||
rb_dictionary *auth_clients;
|
||||
rb_dictionary *auth_providers; /* Referenced by name */
|
||||
|
||||
static rb_dlink_list free_pids;
|
||||
static uint32_t pid;
|
||||
static struct ev_entry *timeout_ev;
|
||||
|
||||
struct auth_client *
|
||||
find_client(uint16_t cid)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_clients.head)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
|
||||
if(auth->cid == cid)
|
||||
return auth;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct auth_provider *
|
||||
find_provider(const char *name)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(strcasecmp(provider->name, name) == 0)
|
||||
return provider;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initalise all providers */
|
||||
void
|
||||
init_providers(void)
|
||||
{
|
||||
auth_clients = rb_dictionary_create("pending auth clients", rb_uint32cmp);
|
||||
auth_providers = rb_dictionary_create("auth providers", strcmp);
|
||||
timeout_ev = rb_event_addish("provider_timeout_event", provider_timeout_event, NULL, 1);
|
||||
|
||||
load_provider(&rdns_provider);
|
||||
|
@ -109,29 +79,27 @@ init_providers(void)
|
|||
void
|
||||
destroy_providers(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dlink_node *ptr;
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_client *auth;
|
||||
struct auth_provider *provider;
|
||||
|
||||
/* Cancel outstanding connections */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
|
||||
/* XXX - Is it right to reject clients like this?
|
||||
* XXX - double iteration */
|
||||
/* TBD - is this the right thing? */
|
||||
reject_client(auth, UINT32_MAX, "destroy",
|
||||
"Authentication system is down... try reconnecting in a few seconds");
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_providers.head)
|
||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->destroy)
|
||||
provider->destroy();
|
||||
|
||||
rb_dlinkDelete(ptr, &auth_providers);
|
||||
}
|
||||
|
||||
rb_dictionary_destroy(auth_clients, NULL, NULL);
|
||||
rb_dictionary_destroy(auth_providers, NULL, NULL);
|
||||
rb_event_delete(timeout_ev);
|
||||
}
|
||||
|
||||
|
@ -173,7 +141,7 @@ load_provider(struct auth_provider *provider)
|
|||
if(provider->init != NULL)
|
||||
provider->init();
|
||||
|
||||
rb_dlinkAdd(provider, &provider->node, &auth_providers);
|
||||
rb_dictionary_add(auth_providers, provider->name, provider);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -193,7 +161,7 @@ unload_provider(struct auth_provider *provider)
|
|||
if(provider->destroy != NULL)
|
||||
provider->destroy();
|
||||
|
||||
rb_dlinkDelete(&provider->node, &auth_providers);
|
||||
rb_dictionary_delete(auth_providers, provider->name);
|
||||
|
||||
/* Reclaim ID */
|
||||
rb_dlinkAddAlloc(RB_UINT_TO_POINTER(provider->id), &free_pids);
|
||||
|
@ -207,19 +175,18 @@ cancel_providers(struct auth_client *auth)
|
|||
{
|
||||
if(auth->refcount > 0)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_provider *provider;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->cancel != NULL && is_provider_running(auth, provider->id))
|
||||
/* Cancel if required */
|
||||
provider->cancel(auth);
|
||||
}
|
||||
}
|
||||
|
||||
rb_dlinkDelete(&auth->node, &auth_clients);
|
||||
rb_dictionary_delete(auth_clients, RB_UINT_TO_POINTER(auth->cid));
|
||||
rb_free(auth->data);
|
||||
rb_free(auth);
|
||||
}
|
||||
|
@ -229,7 +196,8 @@ cancel_providers(struct auth_client *auth)
|
|||
void
|
||||
provider_done(struct auth_client *auth, uint32_t id)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_provider *provider;
|
||||
|
||||
lrb_assert(is_provider_running(auth, id));
|
||||
lrb_assert(id != UINT32_MAX);
|
||||
|
@ -244,10 +212,8 @@ provider_done(struct auth_client *auth, uint32_t id)
|
|||
return;
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->completed != NULL && is_provider_running(auth, provider->id))
|
||||
/* Notify pending clients who asked for it */
|
||||
provider->completed(auth, id);
|
||||
|
@ -301,17 +267,18 @@ accept_client(struct auth_client *auth, uint32_t id)
|
|||
static 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 *provider;
|
||||
struct auth_client *auth = rb_malloc(sizeof(struct auth_client));
|
||||
long lcid = strtol(cid, NULL, 16);
|
||||
rb_dlink_node *ptr;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
if(lcid >= UINT32_MAX)
|
||||
return;
|
||||
|
||||
auth->cid = (uint32_t)lcid;
|
||||
|
||||
if(find_client(auth->cid) == NULL)
|
||||
rb_dlinkAdd(auth, &auth->node, &auth_clients);
|
||||
if(rb_dictionary_find(auth_clients, RB_UINT_TO_POINTER(auth->cid)) == NULL)
|
||||
rb_dictionary_add(auth_clients, RB_UINT_TO_POINTER(auth->cid), auth);
|
||||
else
|
||||
{
|
||||
warn_opers(L_CRIT, "provider: duplicate client added via start_auth: %x", auth->cid);
|
||||
|
@ -331,14 +298,12 @@ start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_
|
|||
rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
|
||||
rb_strlcpy(auth->username, "*", sizeof(auth->username));
|
||||
|
||||
auth->data = rb_malloc(rb_dlink_list_length(&auth_providers) *
|
||||
auth->data = rb_malloc(rb_dictionary_size(auth_providers) *
|
||||
sizeof(struct auth_client_data));
|
||||
|
||||
auth->providers_starting = true;
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
auth->data[provider->id].provider = provider;
|
||||
|
||||
lrb_assert(provider->start != NULL);
|
||||
|
@ -386,7 +351,7 @@ handle_cancel_connection(int parc, char *parv[])
|
|||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if((auth = find_client(lcid)) == NULL)
|
||||
if((auth = rb_dictionary_retrieve(auth_clients, RB_UINT_TO_POINTER((uint32_t)lcid))) == NULL)
|
||||
{
|
||||
/* This could happen as a race if we've accepted/rejected but they cancel, so don't die here.
|
||||
* --Elizafox */
|
||||
|
@ -400,17 +365,16 @@ static void
|
|||
provider_timeout_event(void *notused __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
const time_t curtime = rb_current_time();
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
rb_dlink_node *ptr2;
|
||||
rb_dictionary_iter iter2;
|
||||
struct auth_provider *provider;
|
||||
|
||||
RB_DLINK_FOREACH(ptr2, auth_providers.head)
|
||||
RB_DICTIONARY_FOREACH(provider, &iter2, auth_providers)
|
||||
{
|
||||
struct auth_provider *provider = ptr2->data;
|
||||
const time_t timeout = get_provider_timeout(auth, provider->id);
|
||||
|
||||
if(is_provider_running(auth, provider->id) && provider->timeout != NULL &&
|
||||
|
|
|
@ -44,8 +44,6 @@ struct auth_client_data
|
|||
|
||||
struct auth_client
|
||||
{
|
||||
rb_dlink_node node;
|
||||
|
||||
uint16_t cid; /* Client ID */
|
||||
|
||||
char l_ip[HOSTIPLEN + 1]; /* Listener IP address */
|
||||
|
@ -106,12 +104,8 @@ extern struct auth_provider ident_provider;
|
|||
extern struct auth_provider blacklist_provider;
|
||||
extern struct auth_provider opm_provider;
|
||||
|
||||
extern rb_dlink_list auth_providers;
|
||||
extern rb_dlink_list auth_clients;
|
||||
|
||||
struct auth_client * find_client(uint16_t cid);
|
||||
|
||||
struct auth_provider * find_provider(const char *name);
|
||||
extern rb_dictionary *auth_providers;
|
||||
extern rb_dictionary *auth_clients;
|
||||
|
||||
void load_provider(struct auth_provider *provider);
|
||||
void unload_provider(struct auth_provider *provider);
|
||||
|
@ -128,11 +122,18 @@ void handle_new_connection(int parc, char *parv[]);
|
|||
void handle_cancel_connection(int parc, char *parv[]);
|
||||
|
||||
|
||||
/* Get a provider by name */
|
||||
static inline struct auth_provider *
|
||||
get_provider(const char *name)
|
||||
{
|
||||
return rb_dictionary_retrieve(auth_providers, name);
|
||||
}
|
||||
|
||||
/* Get a provider's id by name */
|
||||
static inline bool
|
||||
get_provider_id(const char *name, uint32_t *id)
|
||||
{
|
||||
struct auth_provider *provider = find_provider(name);
|
||||
struct auth_provider *provider = get_provider(name);
|
||||
|
||||
if(provider != NULL)
|
||||
{
|
||||
|
|
|
@ -421,11 +421,11 @@ blacklists_cancel(struct auth_client *auth)
|
|||
static void
|
||||
blacklists_destroy(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_client *auth;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
blacklists_cancel(auth);
|
||||
}
|
||||
|
||||
|
|
|
@ -275,13 +275,12 @@ get_valid_ident(char *buf)
|
|||
static void
|
||||
ident_destroy(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Nuke all ident queries */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
|
||||
if(get_provider_data(auth, SELF_PID) != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
|
|
|
@ -196,10 +196,11 @@ read_opm_reply(rb_fde_t *F, void *data)
|
|||
static void
|
||||
accept_opm(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
|
||||
{
|
||||
struct auth_client *auth = NULL;
|
||||
struct opm_listener *listener = data;
|
||||
struct rb_sockaddr_storage localaddr;
|
||||
unsigned int llen = sizeof(struct rb_sockaddr_storage);
|
||||
rb_dlink_node *ptr;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
if(status != 0 || listener == NULL)
|
||||
{
|
||||
|
@ -215,10 +216,8 @@ accept_opm(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, voi
|
|||
}
|
||||
|
||||
/* Correlate connection with client(s) */
|
||||
RB_DLINK_FOREACH(ptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
|
||||
if(GET_SS_FAMILY(&auth->c_addr) != GET_SS_FAMILY(&localaddr))
|
||||
continue;
|
||||
|
||||
|
@ -468,9 +467,10 @@ establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
|||
static bool
|
||||
create_listener(const char *ip, uint16_t port)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
struct opm_listener *listener;
|
||||
struct rb_sockaddr_storage addr;
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
rb_fde_t *F;
|
||||
int opt = 1;
|
||||
|
||||
|
@ -560,9 +560,8 @@ create_listener(const char *ip, uint16_t port)
|
|||
/* Cancel clients that may be on old listener
|
||||
* XXX - should rescan clients that need it
|
||||
*/
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
opm_cancel(auth);
|
||||
}
|
||||
|
||||
|
@ -675,12 +674,12 @@ opm_cancel(struct auth_client *auth)
|
|||
static void
|
||||
opm_destroy(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Nuke all opm lookups */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
opm_cancel(auth);
|
||||
}
|
||||
}
|
||||
|
@ -709,7 +708,8 @@ set_opm_enabled(const char *key __unused, int parc __unused, const char **parv)
|
|||
{
|
||||
if(listeners[LISTEN_IPV4].F != NULL || listeners[LISTEN_IPV6].F != NULL)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Close the listening socket */
|
||||
if(listeners[LISTEN_IPV4].F != NULL)
|
||||
|
@ -720,9 +720,8 @@ set_opm_enabled(const char *key __unused, int parc __unused, const char **parv)
|
|||
|
||||
listeners[LISTEN_IPV4].F = listeners[LISTEN_IPV6].F = NULL;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
opm_cancel(auth);
|
||||
}
|
||||
}
|
||||
|
@ -815,10 +814,11 @@ create_opm_scanner(const char *key __unused, int parc __unused, const char **par
|
|||
static void
|
||||
delete_opm_scanner(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
struct opm_proxy *proxy;
|
||||
protocol_t proto = get_protocol_from_string(parv[0]);
|
||||
int iport = atoi(parv[1]);
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
if(iport <= 0 || iport > 65535)
|
||||
{
|
||||
|
@ -839,18 +839,17 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par
|
|||
}
|
||||
|
||||
/* Abort remaining clients on this scanner */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
rb_dlink_node *ptr;
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
rb_dlink_node *optr;
|
||||
|
||||
if(lookup == NULL)
|
||||
continue;
|
||||
|
||||
RB_DLINK_FOREACH(optr, lookup->scans.head)
|
||||
RB_DLINK_FOREACH(ptr, lookup->scans.head)
|
||||
{
|
||||
struct opm_scan *scan = optr->data;
|
||||
struct opm_scan *scan = ptr->data;
|
||||
|
||||
if(scan->proxy->port == proxy->port && scan->proxy->proto == proxy->proto)
|
||||
{
|
||||
|
@ -876,7 +875,9 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par
|
|||
static void
|
||||
delete_opm_scanner_all(const char *key __unused, int parc __unused, const char **parv __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, proxy_scanners.head)
|
||||
{
|
||||
|
@ -884,9 +885,8 @@ delete_opm_scanner_all(const char *key __unused, int parc __unused, const char *
|
|||
rb_dlinkDelete(ptr, &proxy_scanners);
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
opm_cancel(auth);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,12 +112,11 @@ client_success(struct auth_client *auth)
|
|||
static void
|
||||
rdns_destroy(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_clients.head)
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
struct auth_client *auth = ptr->data;
|
||||
|
||||
if(get_provider_data(auth, SELF_PID) != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue