diff --git a/authd/provider.c b/authd/provider.c index c9c7b2c4..f7574b99 100644 --- a/authd/provider.c +++ b/authd/provider.c @@ -54,67 +54,21 @@ static EVH provider_timeout_event; -rb_dlink_list auth_providers; - -/* Clients waiting */ 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; -/* Load a provider */ -void -load_provider(struct auth_provider *provider) -{ - if(rb_dlink_list_length(&auth_providers) >= MAX_PROVIDERS) - { - warn_opers(L_WARN, "provider: cannot load provider with id %d: maximum reached (%d)", - provider->id, MAX_PROVIDERS); - return; - } - - if(provider->opt_handlers != NULL) - { - struct auth_opts_handler *handler; - - for(handler = provider->opt_handlers; handler->option != NULL; handler++) - rb_dictionary_add(authd_option_handlers, handler->option, handler); - } - - if(provider->stats_handler.letter != '\0') - authd_stat_handlers[provider->stats_handler.letter] = provider->stats_handler.handler; - - if(provider->init != NULL) - provider->init(); - - rb_dlinkAddTail(provider, &provider->node, &auth_providers); -} - -void -unload_provider(struct auth_provider *provider) -{ - if(provider->opt_handlers != NULL) - { - struct auth_opts_handler *handler; - - for(handler = provider->opt_handlers; handler->option != NULL; handler++) - rb_dictionary_delete(authd_option_handlers, handler->option); - } - - if(provider->stats_handler.letter != '\0') - authd_stat_handlers[provider->stats_handler.letter] = NULL; - - if(provider->destroy != NULL) - provider->destroy(); - - rb_dlinkDelete(&provider->node, &auth_providers); -} - /* 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); load_provider(&ident_provider); load_provider(&blacklist_provider); @@ -137,28 +91,81 @@ destroy_providers(void) reject_client(auth, -1, "destroy", "Authentication system is down... try reconnecting in a few seconds"); } - RB_DLINK_FOREACH(ptr, auth_providers.head) + RB_DICTIONARY_FOREACH(provider, &iter, auth_providers) { - provider = ptr->data; - if(provider->destroy) provider->destroy(); } + rb_dictionary_destroy(auth_clients, NULL, NULL); + rb_dictionary_destroy(auth_providers, NULL, NULL); rb_event_delete(timeout_ev); } +/* Load a provider */ +void +load_provider(struct auth_provider *provider) +{ + /* Assign a PID */ + if(rb_dlink_list_length(&free_pids) > 0) + { + /* use the free list */ + provider->id = RB_POINTER_TO_UINT(free_pids.head->data); + rb_dlinkDestroy(free_pids.head, &free_pids); + } + else + provider->id = pid++; + + if(provider->opt_handlers != NULL) + { + struct auth_opts_handler *handler; + + for(handler = provider->opt_handlers; handler->option != NULL; handler++) + rb_dictionary_add(authd_option_handlers, handler->option, handler); + } + + if(provider->stats_handler.letter != '\0') + authd_stat_handlers[provider->stats_handler.letter] = provider->stats_handler.handler; + + if(provider->init != NULL) + provider->init(); + + rb_dictionary_add(auth_providers, provider->name, provider); +} + +void +unload_provider(struct auth_provider *provider) +{ + if(provider->opt_handlers != NULL) + { + struct auth_opts_handler *handler; + + for(handler = provider->opt_handlers; handler->option != NULL; handler++) + rb_dictionary_delete(authd_option_handlers, handler->option); + } + + if(provider->stats_handler.letter != '\0') + authd_stat_handlers[provider->stats_handler.letter] = NULL; + + if(provider->destroy != NULL) + provider->destroy(); + + rb_dictionary_delete(auth_providers, provider->name); + + /* Reclaim ID */ + rb_dlinkAddAlloc(RB_UINT_TO_POINTER(provider->id), &free_pids); +} + + /* Cancel outstanding providers for a client */ void cancel_providers(struct auth_client *auth) { - 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) { - provider = ptr->data; - if(provider->cancel && is_provider_running(auth, provider->id)) /* Cancel if required */ provider->cancel(auth); @@ -171,9 +178,9 @@ cancel_providers(struct auth_client *auth) /* Provider is done - WARNING: do not use auth instance after calling! */ void -provider_done(struct auth_client *auth, provider_t id) +provider_done(struct auth_client *auth, uint32_t id) { - rb_dlink_node *ptr; + rb_dictionary_iter iter; struct auth_provider *provider; set_provider_done(auth, id); @@ -186,10 +193,8 @@ provider_done(struct auth_client *auth, provider_t id) return; } - RB_DLINK_FOREACH(ptr, auth_providers.head) + RB_DICTIONARY_FOREACH(provider, &iter, auth_providers) { - provider = ptr->data; - if(provider->completed != NULL && is_provider_running(auth, provider->id)) /* Notify pending clients who asked for it */ provider->completed(auth, id); @@ -198,31 +203,11 @@ provider_done(struct auth_client *auth, provider_t id) /* Reject a client - WARNING: do not use auth instance after calling! */ void -reject_client(struct auth_client *auth, provider_t id, const char *data, const char *fmt, ...) +reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...) { - char reject; char buf[BUFSIZE]; va_list args; - switch(id) - { - case PROVIDER_RDNS: - reject = 'D'; - break; - case PROVIDER_IDENT: - reject = 'I'; - break; - case PROVIDER_BLACKLIST: - reject = 'B'; - break; - case PROVIDER_OPM: - reject = 'O'; - break; - default: - reject = 'N'; - break; - } - if(data == NULL) data = "*"; @@ -234,7 +219,10 @@ reject_client(struct auth_client *auth, provider_t id, const char *data, const c * In the future this may not be the case. * --Elizafox */ - rb_helper_write(authd_helper, "R %x %c %s %s %s :%s", auth->cid, reject, auth->username, auth->hostname, data, buf); + rb_helper_write(authd_helper, "R %x %c %s %s %s :%s", + auth->cid, auth->data[id].provider->letter, + auth->username, auth->hostname, + data, buf); set_provider_done(auth, id); cancel_providers(auth); @@ -242,7 +230,7 @@ reject_client(struct auth_client *auth, provider_t id, const char *data, const c /* Accept a client, cancel outstanding providers if any - WARNING: do nto use auth instance after calling! */ void -accept_client(struct auth_client *auth, provider_t id) +accept_client(struct auth_client *auth, uint32_t id) { rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname); @@ -257,7 +245,7 @@ start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_ 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; @@ -285,13 +273,13 @@ 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) { - provider = ptr->data; + auth->data[provider->id].provider = provider; lrb_assert(provider->start != NULL); @@ -360,11 +348,11 @@ provider_timeout_event(void *notused __unused) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { - rb_dlink_node *ptr; + rb_dictionary_iter iter2; + struct auth_provider *provider; - RB_DLINK_FOREACH(ptr, auth_providers.head) + RB_DICTIONARY_FOREACH(provider, &iter2, auth_providers) { - struct auth_provider *provider = ptr->data; const time_t timeout = get_provider_timeout(auth, provider->id); if(is_provider_running(auth, provider->id) && provider->timeout != NULL && diff --git a/authd/provider.h b/authd/provider.h index b04cf009..2e8179fb 100644 --- a/authd/provider.h +++ b/authd/provider.h @@ -27,15 +27,6 @@ #define MAX_PROVIDERS 32 /* This should be enough */ -/* Registered providers */ -typedef enum -{ - PROVIDER_RDNS, - PROVIDER_IDENT, - PROVIDER_BLACKLIST, - PROVIDER_OPM, -} provider_t; - typedef enum { PROVIDER_STATUS_NOTRUN = 0, @@ -45,6 +36,7 @@ typedef enum struct auth_client_data { + struct auth_provider *provider; /* Pointer back */ time_t timeout; /* Provider timeout */ void *data; /* Provider data */ provider_status_t status; /* Provider status */ @@ -76,8 +68,8 @@ typedef void (*provider_destroy_t)(void); typedef bool (*provider_start_t)(struct auth_client *); typedef void (*provider_cancel_t)(struct auth_client *); -typedef void (*provider_timeout_t)(struct auth_client *); -typedef void (*provider_complete_t)(struct auth_client *, provider_t); +typedef void (*uint32_timeout_t)(struct auth_client *); +typedef void (*provider_complete_t)(struct auth_client *, uint32_t); struct auth_stats_handler { @@ -89,14 +81,17 @@ struct auth_provider { rb_dlink_node node; - provider_t id; + uint32_t id; /* Provider ID */ + + const char *name; /* Name of the provider */ + char letter; /* Letter used on reject, etc. */ provider_init_t init; /* Initalise the provider */ provider_destroy_t destroy; /* Terminate the provider */ provider_start_t start; /* Perform authentication */ provider_cancel_t cancel; /* Authentication cancelled */ - provider_timeout_t timeout; /* Timeout callback */ + uint32_timeout_t timeout; /* Timeout callback */ provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */ struct auth_stats_handler stats_handler; @@ -109,7 +104,7 @@ 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_dictionary *auth_providers; extern rb_dictionary *auth_clients; void load_provider(struct auth_provider *provider); @@ -119,24 +114,46 @@ void init_providers(void); void destroy_providers(void); void cancel_providers(struct auth_client *auth); -void provider_done(struct auth_client *auth, provider_t id); -void accept_client(struct auth_client *auth, provider_t id); -void reject_client(struct auth_client *auth, provider_t id, const char *data, const char *fmt, ...); +void provider_done(struct auth_client *auth, uint32_t id); +void accept_client(struct auth_client *auth, uint32_t id); +void reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...); 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, int *id) +{ + struct auth_provider *provider = get_provider(name); + + if(provider != NULL) + { + *id = provider->id; + return true; + } + else + return false; +} + /* Get a provider's raw status */ static inline provider_status_t -get_provider_status(struct auth_client *auth, provider_t provider) +get_provider_status(struct auth_client *auth, uint32_t provider) { return auth->data[provider].status; } /* Set a provider's raw status */ static inline void -set_provider_status(struct auth_client *auth, provider_t provider, provider_status_t status) +set_provider_status(struct auth_client *auth, uint32_t provider, provider_status_t status) { auth->data[provider].status = status; } @@ -144,7 +161,7 @@ set_provider_status(struct auth_client *auth, provider_t provider, provider_stat /* Set the provider as running * If you're doing asynchronous work call this */ static inline void -set_provider_running(struct auth_client *auth, provider_t provider) +set_provider_running(struct auth_client *auth, uint32_t provider) { auth->refcount++; set_provider_status(auth, provider, PROVIDER_STATUS_RUNNING); @@ -153,7 +170,7 @@ set_provider_running(struct auth_client *auth, provider_t provider) /* Provider is no longer operating on this auth client * You should use provider_done and not this */ static inline void -set_provider_done(struct auth_client *auth, provider_t provider) +set_provider_done(struct auth_client *auth, uint32_t provider) { auth->refcount--; set_provider_status(auth, provider, PROVIDER_STATUS_DONE); @@ -161,14 +178,14 @@ set_provider_done(struct auth_client *auth, provider_t provider) /* Check if provider is operating on this auth client */ static inline bool -is_provider_running(struct auth_client *auth, provider_t provider) +is_provider_running(struct auth_client *auth, uint32_t provider) { return get_provider_status(auth, provider) == PROVIDER_STATUS_RUNNING; } /* Check if provider has finished on this client */ static inline bool -is_provider_done(struct auth_client *auth, provider_t provider) +is_provider_done(struct auth_client *auth, uint32_t provider) { return get_provider_status(auth, provider) == PROVIDER_STATUS_DONE; } @@ -177,7 +194,6 @@ is_provider_done(struct auth_client *auth, provider_t provider) static inline void * get_provider_data(struct auth_client *auth, uint32_t id) { - lrb_assert(id < rb_dlink_list_length(&auth_providers)); return auth->data[id].data; } @@ -185,7 +201,6 @@ get_provider_data(struct auth_client *auth, uint32_t id) static inline void set_provider_data(struct auth_client *auth, uint32_t id, void *data) { - lrb_assert(id < rb_dlink_list_length(&auth_providers)); auth->data[id].data = data; } @@ -194,7 +209,6 @@ set_provider_data(struct auth_client *auth, uint32_t id, void *data) static inline void set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t timeout) { - lrb_assert(id < rb_dlink_list_length(&auth_providers)); auth->data[id].timeout = timeout + rb_current_time(); } @@ -203,7 +217,6 @@ set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t time static inline void set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t timeout) { - lrb_assert(id < rb_dlink_list_length(&auth_providers)); auth->data[id].timeout = timeout; } @@ -211,7 +224,6 @@ set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t time static inline time_t get_provider_timeout(struct auth_client *auth, uint32_t id) { - lrb_assert(id < rb_dlink_list_length(&auth_providers)); return auth->data[id].timeout; } diff --git a/authd/providers/blacklist.c b/authd/providers/blacklist.c index 1c6abf45..e0278a20 100644 --- a/authd/providers/blacklist.c +++ b/authd/providers/blacklist.c @@ -43,6 +43,8 @@ #include "stdinc.h" #include "dns.h" +#define SELF_PID (blacklist_provider.id) + typedef enum filter_t { FILTER_ALL = 1, @@ -237,7 +239,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d bl = bllookup->bl; auth = bllookup->auth; - if((bluser = get_provider_data(auth, PROVIDER_BLACKLIST)) == NULL) + if((bluser = get_provider_data(auth, SELF_PID)) == NULL) return; if (result != NULL && status && blacklist_check_reply(bllookup, result)) @@ -245,7 +247,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d /* Match found, so proceed no further */ bl->hits++; blacklists_cancel(auth); - reject_client(auth, PROVIDER_BLACKLIST, bl->host, bl->reason); + reject_client(auth, SELF_PID, bl->host, bl->reason); return; } @@ -260,9 +262,9 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d notice_client(auth->cid, "*** IP not found in DNS blacklist%s", rb_dlink_list_length(&blacklist_list) > 1 ? "s" : ""); rb_free(bluser); - set_provider_data(auth, PROVIDER_BLACKLIST, NULL); - set_provider_timeout_absolute(auth, PROVIDER_BLACKLIST, 0); - provider_done(auth, PROVIDER_BLACKLIST); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); + provider_done(auth, SELF_PID); } } @@ -270,7 +272,7 @@ static void initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth) { struct blacklist_lookup *bllookup = rb_malloc(sizeof(struct blacklist_lookup)); - struct blacklist_user *bluser = get_provider_data(auth, PROVIDER_BLACKLIST); + struct blacklist_user *bluser = get_provider_data(auth, SELF_PID); char buf[IRCD_RES_HOSTLEN + 1]; int aftype; @@ -297,7 +299,7 @@ initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth) static inline void lookup_all_blacklists(struct auth_client *auth) { - struct blacklist_user *bluser = get_provider_data(auth, PROVIDER_BLACKLIST); + struct blacklist_user *bluser = get_provider_data(auth, SELF_PID); rb_dlink_node *ptr; notice_client(auth->cid, "*** Checking your IP against DNS blacklist%s", @@ -311,7 +313,7 @@ lookup_all_blacklists(struct auth_client *auth) initiate_blacklist_dnsquery(bl, auth); } - set_provider_timeout_relative(auth, PROVIDER_BLACKLIST, blacklist_timeout); + set_provider_timeout_relative(auth, SELF_PID, blacklist_timeout); } static inline void @@ -341,7 +343,9 @@ delete_all_blacklists(void) static bool blacklists_start(struct auth_client *auth) { - lrb_assert(get_provider_data(auth, PROVIDER_BLACKLIST) == NULL); + uint32_t rdns_pid, ident_pid; + + lrb_assert(get_provider_data(auth, SELF_PID) == NULL); if(!rb_dlink_list_length(&blacklist_list)) { @@ -350,31 +354,36 @@ blacklists_start(struct auth_client *auth) return true; } - set_provider_data(auth, PROVIDER_BLACKLIST, rb_malloc(sizeof(struct blacklist_user))); + set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct blacklist_user))); - if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)) - /* This probably can't happen but let's handle this case anyway */ + if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && + (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) + { + /* Start the lookup if ident and rdns are finished, or not loaded. */ lookup_all_blacklists(auth); + } - set_provider_running(auth, PROVIDER_BLACKLIST); + set_provider_running(auth, SELF_PID); return true; } /* This is called every time a provider is completed as long as we are marked not done */ static void -blacklists_initiate(struct auth_client *auth, provider_t provider) +blacklists_initiate(struct auth_client *auth, uint32_t provider) { - struct blacklist_user *bluser = get_provider_data(auth, PROVIDER_BLACKLIST); + struct blacklist_user *bluser = get_provider_data(auth, SELF_PID); + uint32_t rdns_pid, ident_pid; - lrb_assert(provider != PROVIDER_BLACKLIST); - lrb_assert(!is_provider_done(auth, PROVIDER_BLACKLIST)); + lrb_assert(provider != SELF_PID); + lrb_assert(!is_provider_done(auth, SELF_PID)); lrb_assert(rb_dlink_list_length(&blacklist_list) > 0); if(bluser == NULL || rb_dlink_list_length(&bluser->queries)) /* Nothing to do */ return; - else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT))) - /* Don't start until we've completed these */ + else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && + (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) + /* Don't start until ident and rdns are finished (or not loaded) */ return; else lookup_all_blacklists(auth); @@ -384,7 +393,7 @@ static void blacklists_cancel(struct auth_client *auth) { rb_dlink_node *ptr, *nptr; - struct blacklist_user *bluser = get_provider_data(auth, PROVIDER_BLACKLIST); + struct blacklist_user *bluser = get_provider_data(auth, SELF_PID); if(bluser == NULL) return; @@ -406,9 +415,9 @@ blacklists_cancel(struct auth_client *auth) } rb_free(bluser); - set_provider_data(auth, PROVIDER_BLACKLIST, NULL); - set_provider_timeout_absolute(auth, PROVIDER_BLACKLIST, 0); - provider_done(auth, PROVIDER_BLACKLIST); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); + provider_done(auth, SELF_PID); } static void @@ -549,7 +558,8 @@ struct auth_opts_handler blacklist_options[] = struct auth_provider blacklist_provider = { - .id = PROVIDER_BLACKLIST, + .name = "blacklist", + .letter = 'B', .destroy = blacklists_destroy, .start = blacklists_start, .cancel = blacklists_cancel, diff --git a/authd/providers/ident.c b/authd/providers/ident.c index 2f08c550..40b67f9b 100644 --- a/authd/providers/ident.c +++ b/authd/providers/ident.c @@ -31,6 +31,8 @@ #include "provider.h" #include "res.h" +#define SELF_PID (ident_provider.id) + #define IDENT_BUFSIZE 128 struct ident_query @@ -88,7 +90,7 @@ ident_connected(rb_fde_t *F __unused, int error, void *data) int authlen; lrb_assert(auth != NULL); - query = get_provider_data(auth, PROVIDER_IDENT); + query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); /* Check the error */ @@ -125,7 +127,7 @@ read_ident_reply(rb_fde_t *F, void *data) int count; lrb_assert(auth != NULL); - query = get_provider_data(auth, PROVIDER_IDENT); + query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); len = rb_read(F, buf, IDENT_BUFSIZE); @@ -170,7 +172,7 @@ read_ident_reply(rb_fde_t *F, void *data) static void client_fail(struct auth_client *auth, ident_message report) { - struct ident_query *query = get_provider_data(auth, PROVIDER_IDENT); + struct ident_query *query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); @@ -180,17 +182,17 @@ client_fail(struct auth_client *auth, ident_message report) rb_close(query->F); rb_free(query); - set_provider_data(auth, PROVIDER_IDENT, NULL); - set_provider_timeout_absolute(auth, PROVIDER_IDENT, 0); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); notice_client(auth->cid, messages[report]); - provider_done(auth, PROVIDER_IDENT); + provider_done(auth, SELF_PID); } static void client_success(struct auth_client *auth) { - struct ident_query *query = get_provider_data(auth, PROVIDER_IDENT); + struct ident_query *query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); @@ -198,11 +200,11 @@ client_success(struct auth_client *auth) rb_close(query->F); rb_free(query); - set_provider_data(auth, PROVIDER_IDENT, NULL); - set_provider_timeout_absolute(auth, PROVIDER_IDENT, 0); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); notice_client(auth->cid, messages[REPORT_FOUND]); - provider_done(auth, PROVIDER_IDENT); + provider_done(auth, SELF_PID); } /* get_valid_ident @@ -278,7 +280,7 @@ ident_destroy(void) /* Nuke all ident queries */ RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { - if(get_provider_data(auth, PROVIDER_IDENT) != NULL) + if(get_provider_data(auth, SELF_PID) != NULL) client_fail(auth, REPORT_FAIL); } } @@ -290,20 +292,20 @@ ident_start(struct auth_client *auth) struct rb_sockaddr_storage l_addr, c_addr; int family = GET_SS_FAMILY(&auth->c_addr); - lrb_assert(get_provider_data(auth, PROVIDER_IDENT) == NULL); + lrb_assert(get_provider_data(auth, SELF_PID) == NULL); if(!ident_enable) { rb_free(query); notice_client(auth->cid, messages[REPORT_DISABLED]); - set_provider_done(auth, PROVIDER_IDENT); + set_provider_done(auth, SELF_PID); return true; } notice_client(auth->cid, messages[REPORT_LOOKUP]); - set_provider_data(auth, PROVIDER_IDENT, query); - set_provider_timeout_relative(auth, PROVIDER_IDENT, ident_timeout); + set_provider_data(auth, SELF_PID, query); + set_provider_timeout_relative(auth, SELF_PID, ident_timeout); if((query->F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL) { @@ -324,7 +326,7 @@ ident_start(struct auth_client *auth) GET_SS_LEN(&l_addr), ident_connected, auth, ident_timeout); - set_provider_running(auth, PROVIDER_IDENT); + set_provider_running(auth, SELF_PID); return true; } @@ -332,7 +334,7 @@ ident_start(struct auth_client *auth) static void ident_cancel(struct auth_client *auth) { - struct ident_query *query = get_provider_data(auth, PROVIDER_IDENT); + struct ident_query *query = get_provider_data(auth, SELF_PID); if(query != NULL) client_fail(auth, REPORT_FAIL); @@ -368,7 +370,8 @@ struct auth_opts_handler ident_options[] = struct auth_provider ident_provider = { - .id = PROVIDER_IDENT, + .name = "ident", + .letter = 'I', .start = ident_start, .destroy = ident_destroy, .cancel = ident_cancel, diff --git a/authd/providers/opm.c b/authd/providers/opm.c index 4f0b3d5c..56150bfc 100644 --- a/authd/providers/opm.c +++ b/authd/providers/opm.c @@ -25,6 +25,8 @@ #include "notice.h" #include "provider.h" +#define SELF_PID (opm_provider.id) + #define OPM_READSIZE 128 typedef enum protocol_t @@ -133,7 +135,7 @@ read_opm_reply(rb_fde_t *F, void *data) ssize_t len; lrb_assert(auth != NULL); - lookup = get_provider_data(auth, PROVIDER_OPM); + lookup = get_provider_data(auth, SELF_PID); lrb_assert(lookup != NULL); if((len = rb_read(F, readbuf, sizeof(readbuf))) < 0 && rb_ignore_errno(errno)) @@ -168,7 +170,7 @@ read_opm_reply(rb_fde_t *F, void *data) /* No longer needed, client is going away */ rb_free(lookup); - reject_client(auth, PROVIDER_OPM, readbuf, "Open proxy detected"); + reject_client(auth, SELF_PID, readbuf, "Open proxy detected"); break; } } @@ -260,7 +262,7 @@ socks4_connected(rb_fde_t *F, int error, void *data) lrb_assert(scan != NULL); auth = scan->auth; - lookup = get_provider_data(auth, PROVIDER_OPM); + lookup = get_provider_data(auth, SELF_PID); memcpy(c, "\x04\x01", 2); c += 2; /* Socks version 4, connect command */ @@ -315,7 +317,7 @@ socks5_connected(rb_fde_t *F, int error, void *data) lrb_assert(scan != NULL); auth = scan->auth; - lookup = get_provider_data(auth, PROVIDER_OPM); + lookup = get_provider_data(auth, SELF_PID); /* Build the version header and socks request * version header (3 bytes): version, number of auth methods, auth type (0 for none) @@ -380,7 +382,7 @@ http_connect_connected(rb_fde_t *F, int error, void *data) lrb_assert(scan != NULL); auth = scan->auth; - lookup = get_provider_data(auth, PROVIDER_OPM); + lookup = get_provider_data(auth, SELF_PID); switch(GET_SS_FAMILY(&auth->c_addr)) { @@ -425,7 +427,7 @@ end: static inline void establish_connection(struct auth_client *auth, struct opm_proxy *proxy) { - struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM); + struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); struct opm_listener *listener; struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan)); struct rb_sockaddr_storage c_a, l_a; @@ -617,8 +619,8 @@ opm_scan(struct auth_client *auth) lrb_assert(auth != NULL); - lookup = get_provider_data(auth, PROVIDER_OPM); - set_provider_timeout_relative(auth, PROVIDER_OPM, opm_timeout); + lookup = get_provider_data(auth, SELF_PID); + set_provider_timeout_relative(auth, SELF_PID, opm_timeout); lookup->in_progress = true; @@ -633,19 +635,21 @@ opm_scan(struct auth_client *auth) /* This is called every time a provider is completed as long as we are marked not done */ static void -blacklists_initiate(struct auth_client *auth, provider_t provider) +blacklists_initiate(struct auth_client *auth, uint32_t provider) { - struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM); + struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); + uint32_t rdns_pid, ident_pid; - lrb_assert(provider != PROVIDER_OPM); - lrb_assert(!is_provider_done(auth, PROVIDER_OPM)); + lrb_assert(provider != SELF_PID); + lrb_assert(!is_provider_done(auth, SELF_PID)); lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0); if(lookup == NULL || lookup->in_progress) /* Nothing to do */ return; - else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT))) - /* Don't start until we've completed these */ + else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && + (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) + /* Don't start until ident and rdns are finished (or not loaded) */ return; else opm_scan(auth); @@ -654,7 +658,9 @@ blacklists_initiate(struct auth_client *auth, provider_t provider) static bool opm_start(struct auth_client *auth) { - lrb_assert(get_provider_data(auth, PROVIDER_OPM) == NULL); + uint32_t rdns_pid, ident_pid; + + lrb_assert(get_provider_data(auth, SELF_PID) == NULL); if(!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0) { @@ -663,20 +669,23 @@ opm_start(struct auth_client *auth) return true; } - set_provider_data(auth, PROVIDER_BLACKLIST, rb_malloc(sizeof(struct opm_lookup))); + set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct opm_lookup))); - if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)) - /* This probably can't happen but let's handle this case anyway */ + if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && + (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) + { + /* Don't start until ident and rdns are finished (or not loaded) */ opm_scan(auth); + } - set_provider_running(auth, PROVIDER_BLACKLIST); + set_provider_running(auth, SELF_PID); return true; } static void opm_cancel(struct auth_client *auth) { - struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM); + struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); if(lookup != NULL) { @@ -694,9 +703,9 @@ opm_cancel(struct auth_client *auth) rb_free(lookup); - set_provider_data(auth, PROVIDER_OPM, NULL); - set_provider_timeout_absolute(auth, PROVIDER_OPM, 0); - provider_done(auth, PROVIDER_OPM); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); + provider_done(auth, SELF_PID); } } @@ -869,7 +878,7 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { rb_dlink_node *ptr; - struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM); + struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); if(lookup == NULL) continue; @@ -934,7 +943,8 @@ struct auth_opts_handler opm_options[] = struct auth_provider opm_provider = { - .id = PROVIDER_OPM, + .name = "opm", + .letter = 'O', .destroy = opm_destroy, .start = opm_start, .cancel = opm_cancel, diff --git a/authd/providers/rdns.c b/authd/providers/rdns.c index 25cd2813..5583fd6e 100644 --- a/authd/providers/rdns.c +++ b/authd/providers/rdns.c @@ -26,6 +26,8 @@ #include "res.h" #include "dns.h" +#define SELF_PID (rdns_provider.id) + struct user_query { struct dns_query *query; /* Pending DNS query */ @@ -56,7 +58,7 @@ static void dns_answer_callback(const char *res, bool status, query_type type, void *data) { struct auth_client *auth = data; - struct user_query *query = get_provider_data(auth, PROVIDER_RDNS); + struct user_query *query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); @@ -74,7 +76,7 @@ dns_answer_callback(const char *res, bool status, query_type type, void *data) static void client_fail(struct auth_client *auth, dns_message report) { - struct user_query *query = get_provider_data(auth, PROVIDER_RDNS); + struct user_query *query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); @@ -85,15 +87,15 @@ client_fail(struct auth_client *auth, dns_message report) rb_free(query); - set_provider_data(auth, PROVIDER_RDNS, NULL); - set_provider_timeout_absolute(auth, PROVIDER_RDNS, 0); - provider_done(auth, PROVIDER_RDNS); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); + provider_done(auth, SELF_PID); } static void client_success(struct auth_client *auth) { - struct user_query *query = get_provider_data(auth, PROVIDER_RDNS); + struct user_query *query = get_provider_data(auth, SELF_PID); lrb_assert(query != NULL); @@ -102,9 +104,9 @@ client_success(struct auth_client *auth) rb_free(query); - set_provider_data(auth, PROVIDER_RDNS, NULL); - set_provider_timeout_absolute(auth, PROVIDER_RDNS, 0); - provider_done(auth, PROVIDER_RDNS); + set_provider_data(auth, SELF_PID, NULL); + set_provider_timeout_absolute(auth, SELF_PID, 0); + provider_done(auth, SELF_PID); } static void @@ -115,7 +117,7 @@ rdns_destroy(void) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { - if(get_provider_data(auth, PROVIDER_RDNS) != NULL) + if(get_provider_data(auth, SELF_PID) != NULL) client_fail(auth, REPORT_FAIL); } } @@ -125,20 +127,20 @@ rdns_start(struct auth_client *auth) { struct user_query *query = rb_malloc(sizeof(struct user_query)); - set_provider_data(auth, PROVIDER_RDNS, query); - set_provider_timeout_relative(auth, PROVIDER_RDNS, rdns_timeout); + set_provider_data(auth, SELF_PID, query); + set_provider_timeout_relative(auth, SELF_PID, rdns_timeout); query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth); notice_client(auth->cid, messages[REPORT_LOOKUP]); - set_provider_running(auth, PROVIDER_RDNS); + set_provider_running(auth, SELF_PID); return true; } static void rdns_cancel(struct auth_client *auth) { - struct user_query *query = get_provider_data(auth, PROVIDER_RDNS); + struct user_query *query = get_provider_data(auth, SELF_PID); if(query != NULL) client_fail(auth, REPORT_FAIL); @@ -166,7 +168,8 @@ struct auth_opts_handler rdns_options[] = struct auth_provider rdns_provider = { - .id = PROVIDER_RDNS, + .name = "rdns", + .letter = 'R', .destroy = rdns_destroy, .start = rdns_start, .cancel = rdns_cancel, diff --git a/ircd/s_user.c b/ircd/s_user.c index 453aa471..a3c34c94 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -467,7 +467,7 @@ register_local_user(struct Client *client_p, struct Client *source_p) return CLIENT_EXITED; } break; - case 'O': + case 'O': /* OPM */ if(IsExemptKline(source_p) || IsConfExemptProxy(aconf)) { sendto_one_notice(source_p, ":*** Your IP address %s has been detected as an open proxy (ip:port %s), but you are exempt", diff --git a/librb/src/dictionary.c b/librb/src/dictionary.c index eeac439f..de55cf8a 100644 --- a/librb/src/dictionary.c +++ b/librb/src/dictionary.c @@ -704,14 +704,14 @@ rb_dictionary_element *rb_dictionary_add(rb_dictionary *dict, const void *key, v * - name of DTree node to delete * * Outputs: - * - on success, the remaining data that needs to be mowgli_freed + * - on success, the remaining data that needs to be rb_freed * - on failure, NULL * * Side Effects: * - data is removed from the DTree. * * Notes: - * - the returned data needs to be mowgli_freed/released manually! + * - the returned data needs to be rb_freed/released manually! */ void *rb_dictionary_delete(rb_dictionary *dtree, const void *key) {