authd: rework module ID system
Provider ID's are now assigned dynamically at load-time. To accomodate this, there is now a lookup system for finding providers by name (all providers have names as well).
This commit is contained in:
parent
376ae2e2a7
commit
731d128990
8 changed files with 232 additions and 206 deletions
174
authd/provider.c
174
authd/provider.c
|
@ -54,67 +54,21 @@
|
||||||
|
|
||||||
static EVH provider_timeout_event;
|
static EVH provider_timeout_event;
|
||||||
|
|
||||||
rb_dlink_list auth_providers;
|
|
||||||
|
|
||||||
/* Clients waiting */
|
|
||||||
rb_dictionary *auth_clients;
|
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;
|
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 */
|
/* Initalise all providers */
|
||||||
void
|
void
|
||||||
init_providers(void)
|
init_providers(void)
|
||||||
{
|
{
|
||||||
auth_clients = rb_dictionary_create("pending auth clients", rb_uint32cmp);
|
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);
|
timeout_ev = rb_event_addish("provider_timeout_event", provider_timeout_event, NULL, 1);
|
||||||
|
|
||||||
load_provider(&rdns_provider);
|
load_provider(&rdns_provider);
|
||||||
load_provider(&ident_provider);
|
load_provider(&ident_provider);
|
||||||
load_provider(&blacklist_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");
|
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)
|
if(provider->destroy)
|
||||||
provider->destroy();
|
provider->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_dictionary_destroy(auth_clients, NULL, NULL);
|
||||||
|
rb_dictionary_destroy(auth_providers, NULL, NULL);
|
||||||
rb_event_delete(timeout_ev);
|
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 */
|
/* Cancel outstanding providers for a client */
|
||||||
void
|
void
|
||||||
cancel_providers(struct auth_client *auth)
|
cancel_providers(struct auth_client *auth)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
rb_dictionary_iter iter;
|
||||||
struct auth_provider *provider;
|
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))
|
if(provider->cancel && is_provider_running(auth, provider->id))
|
||||||
/* Cancel if required */
|
/* Cancel if required */
|
||||||
provider->cancel(auth);
|
provider->cancel(auth);
|
||||||
|
@ -171,9 +178,9 @@ cancel_providers(struct auth_client *auth)
|
||||||
|
|
||||||
/* Provider is done - WARNING: do not use auth instance after calling! */
|
/* Provider is done - WARNING: do not use auth instance after calling! */
|
||||||
void
|
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;
|
struct auth_provider *provider;
|
||||||
|
|
||||||
set_provider_done(auth, id);
|
set_provider_done(auth, id);
|
||||||
|
@ -186,10 +193,8 @@ provider_done(struct auth_client *auth, provider_t id)
|
||||||
return;
|
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))
|
if(provider->completed != NULL && is_provider_running(auth, provider->id))
|
||||||
/* Notify pending clients who asked for it */
|
/* Notify pending clients who asked for it */
|
||||||
provider->completed(auth, id);
|
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! */
|
/* Reject a client - WARNING: do not use auth instance after calling! */
|
||||||
void
|
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];
|
char buf[BUFSIZE];
|
||||||
va_list args;
|
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)
|
if(data == NULL)
|
||||||
data = "*";
|
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.
|
* In the future this may not be the case.
|
||||||
* --Elizafox
|
* --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);
|
set_provider_done(auth, id);
|
||||||
cancel_providers(auth);
|
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! */
|
/* Accept a client, cancel outstanding providers if any - WARNING: do nto use auth instance after calling! */
|
||||||
void
|
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);
|
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_provider *provider;
|
||||||
struct auth_client *auth = rb_malloc(sizeof(struct auth_client));
|
struct auth_client *auth = rb_malloc(sizeof(struct auth_client));
|
||||||
long lcid = strtol(cid, NULL, 16);
|
long lcid = strtol(cid, NULL, 16);
|
||||||
rb_dlink_node *ptr;
|
rb_dictionary_iter iter;
|
||||||
|
|
||||||
if(lcid >= UINT32_MAX)
|
if(lcid >= UINT32_MAX)
|
||||||
return;
|
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->hostname, "*", sizeof(auth->hostname));
|
||||||
rb_strlcpy(auth->username, "*", sizeof(auth->username));
|
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));
|
sizeof(struct auth_client_data));
|
||||||
|
|
||||||
auth->providers_starting = true;
|
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);
|
lrb_assert(provider->start != NULL);
|
||||||
|
|
||||||
|
@ -360,11 +348,11 @@ provider_timeout_event(void *notused __unused)
|
||||||
|
|
||||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
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);
|
const time_t timeout = get_provider_timeout(auth, provider->id);
|
||||||
|
|
||||||
if(is_provider_running(auth, provider->id) && provider->timeout != NULL &&
|
if(is_provider_running(auth, provider->id) && provider->timeout != NULL &&
|
||||||
|
|
|
@ -27,15 +27,6 @@
|
||||||
|
|
||||||
#define MAX_PROVIDERS 32 /* This should be enough */
|
#define MAX_PROVIDERS 32 /* This should be enough */
|
||||||
|
|
||||||
/* Registered providers */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PROVIDER_RDNS,
|
|
||||||
PROVIDER_IDENT,
|
|
||||||
PROVIDER_BLACKLIST,
|
|
||||||
PROVIDER_OPM,
|
|
||||||
} provider_t;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PROVIDER_STATUS_NOTRUN = 0,
|
PROVIDER_STATUS_NOTRUN = 0,
|
||||||
|
@ -45,6 +36,7 @@ typedef enum
|
||||||
|
|
||||||
struct auth_client_data
|
struct auth_client_data
|
||||||
{
|
{
|
||||||
|
struct auth_provider *provider; /* Pointer back */
|
||||||
time_t timeout; /* Provider timeout */
|
time_t timeout; /* Provider timeout */
|
||||||
void *data; /* Provider data */
|
void *data; /* Provider data */
|
||||||
provider_status_t status; /* Provider status */
|
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 bool (*provider_start_t)(struct auth_client *);
|
||||||
typedef void (*provider_cancel_t)(struct auth_client *);
|
typedef void (*provider_cancel_t)(struct auth_client *);
|
||||||
typedef void (*provider_timeout_t)(struct auth_client *);
|
typedef void (*uint32_timeout_t)(struct auth_client *);
|
||||||
typedef void (*provider_complete_t)(struct auth_client *, provider_t);
|
typedef void (*provider_complete_t)(struct auth_client *, uint32_t);
|
||||||
|
|
||||||
struct auth_stats_handler
|
struct auth_stats_handler
|
||||||
{
|
{
|
||||||
|
@ -89,14 +81,17 @@ struct auth_provider
|
||||||
{
|
{
|
||||||
rb_dlink_node node;
|
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_init_t init; /* Initalise the provider */
|
||||||
provider_destroy_t destroy; /* Terminate the provider */
|
provider_destroy_t destroy; /* Terminate the provider */
|
||||||
|
|
||||||
provider_start_t start; /* Perform authentication */
|
provider_start_t start; /* Perform authentication */
|
||||||
provider_cancel_t cancel; /* Authentication cancelled */
|
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) */
|
provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */
|
||||||
|
|
||||||
struct auth_stats_handler stats_handler;
|
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 blacklist_provider;
|
||||||
extern struct auth_provider opm_provider;
|
extern struct auth_provider opm_provider;
|
||||||
|
|
||||||
extern rb_dlink_list auth_providers;
|
extern rb_dictionary *auth_providers;
|
||||||
extern rb_dictionary *auth_clients;
|
extern rb_dictionary *auth_clients;
|
||||||
|
|
||||||
void load_provider(struct auth_provider *provider);
|
void load_provider(struct auth_provider *provider);
|
||||||
|
@ -119,24 +114,46 @@ void init_providers(void);
|
||||||
void destroy_providers(void);
|
void destroy_providers(void);
|
||||||
void cancel_providers(struct auth_client *auth);
|
void cancel_providers(struct auth_client *auth);
|
||||||
|
|
||||||
void provider_done(struct auth_client *auth, provider_t id);
|
void provider_done(struct auth_client *auth, uint32_t id);
|
||||||
void accept_client(struct auth_client *auth, provider_t id);
|
void accept_client(struct auth_client *auth, uint32_t id);
|
||||||
void reject_client(struct auth_client *auth, provider_t id, const char *data, const char *fmt, ...);
|
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_new_connection(int parc, char *parv[]);
|
||||||
void handle_cancel_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 */
|
/* Get a provider's raw status */
|
||||||
static inline provider_status_t
|
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;
|
return auth->data[provider].status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a provider's raw status */
|
/* Set a provider's raw status */
|
||||||
static inline void
|
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;
|
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
|
/* Set the provider as running
|
||||||
* If you're doing asynchronous work call this */
|
* If you're doing asynchronous work call this */
|
||||||
static inline void
|
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++;
|
auth->refcount++;
|
||||||
set_provider_status(auth, provider, PROVIDER_STATUS_RUNNING);
|
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
|
/* Provider is no longer operating on this auth client
|
||||||
* You should use provider_done and not this */
|
* You should use provider_done and not this */
|
||||||
static inline void
|
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--;
|
auth->refcount--;
|
||||||
set_provider_status(auth, provider, PROVIDER_STATUS_DONE);
|
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 */
|
/* Check if provider is operating on this auth client */
|
||||||
static inline bool
|
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;
|
return get_provider_status(auth, provider) == PROVIDER_STATUS_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if provider has finished on this client */
|
/* Check if provider has finished on this client */
|
||||||
static inline bool
|
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;
|
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 *
|
static inline void *
|
||||||
get_provider_data(struct auth_client *auth, uint32_t id)
|
get_provider_data(struct auth_client *auth, uint32_t id)
|
||||||
{
|
{
|
||||||
lrb_assert(id < rb_dlink_list_length(&auth_providers));
|
|
||||||
return auth->data[id].data;
|
return auth->data[id].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +201,6 @@ get_provider_data(struct auth_client *auth, uint32_t id)
|
||||||
static inline void
|
static inline void
|
||||||
set_provider_data(struct auth_client *auth, uint32_t id, void *data)
|
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;
|
auth->data[id].data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +209,6 @@ set_provider_data(struct auth_client *auth, uint32_t id, void *data)
|
||||||
static inline void
|
static inline void
|
||||||
set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t timeout)
|
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();
|
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
|
static inline void
|
||||||
set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t timeout)
|
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;
|
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
|
static inline time_t
|
||||||
get_provider_timeout(struct auth_client *auth, uint32_t id)
|
get_provider_timeout(struct auth_client *auth, uint32_t id)
|
||||||
{
|
{
|
||||||
lrb_assert(id < rb_dlink_list_length(&auth_providers));
|
|
||||||
return auth->data[id].timeout;
|
return auth->data[id].timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
|
|
||||||
|
#define SELF_PID (blacklist_provider.id)
|
||||||
|
|
||||||
typedef enum filter_t
|
typedef enum filter_t
|
||||||
{
|
{
|
||||||
FILTER_ALL = 1,
|
FILTER_ALL = 1,
|
||||||
|
@ -237,7 +239,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d
|
||||||
bl = bllookup->bl;
|
bl = bllookup->bl;
|
||||||
auth = bllookup->auth;
|
auth = bllookup->auth;
|
||||||
|
|
||||||
if((bluser = get_provider_data(auth, PROVIDER_BLACKLIST)) == NULL)
|
if((bluser = get_provider_data(auth, SELF_PID)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (result != NULL && status && blacklist_check_reply(bllookup, result))
|
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 */
|
/* Match found, so proceed no further */
|
||||||
bl->hits++;
|
bl->hits++;
|
||||||
blacklists_cancel(auth);
|
blacklists_cancel(auth);
|
||||||
reject_client(auth, PROVIDER_BLACKLIST, bl->host, bl->reason);
|
reject_client(auth, SELF_PID, bl->host, bl->reason);
|
||||||
return;
|
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",
|
notice_client(auth->cid, "*** IP not found in DNS blacklist%s",
|
||||||
rb_dlink_list_length(&blacklist_list) > 1 ? "s" : "");
|
rb_dlink_list_length(&blacklist_list) > 1 ? "s" : "");
|
||||||
rb_free(bluser);
|
rb_free(bluser);
|
||||||
set_provider_data(auth, PROVIDER_BLACKLIST, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_BLACKLIST, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
provider_done(auth, PROVIDER_BLACKLIST);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +272,7 @@ static void
|
||||||
initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
|
initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
|
||||||
{
|
{
|
||||||
struct blacklist_lookup *bllookup = rb_malloc(sizeof(struct blacklist_lookup));
|
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];
|
char buf[IRCD_RES_HOSTLEN + 1];
|
||||||
int aftype;
|
int aftype;
|
||||||
|
|
||||||
|
@ -297,7 +299,7 @@ initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
|
||||||
static inline void
|
static inline void
|
||||||
lookup_all_blacklists(struct auth_client *auth)
|
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;
|
rb_dlink_node *ptr;
|
||||||
|
|
||||||
notice_client(auth->cid, "*** Checking your IP against DNS blacklist%s",
|
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);
|
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
|
static inline void
|
||||||
|
@ -341,7 +343,9 @@ delete_all_blacklists(void)
|
||||||
static bool
|
static bool
|
||||||
blacklists_start(struct auth_client *auth)
|
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))
|
if(!rb_dlink_list_length(&blacklist_list))
|
||||||
{
|
{
|
||||||
|
@ -350,31 +354,36 @@ blacklists_start(struct auth_client *auth)
|
||||||
return true;
|
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))
|
if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
|
||||||
/* This probably can't happen but let's handle this case anyway */
|
(!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);
|
lookup_all_blacklists(auth);
|
||||||
|
}
|
||||||
|
|
||||||
set_provider_running(auth, PROVIDER_BLACKLIST);
|
set_provider_running(auth, SELF_PID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called every time a provider is completed as long as we are marked not done */
|
/* This is called every time a provider is completed as long as we are marked not done */
|
||||||
static void
|
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(provider != SELF_PID);
|
||||||
lrb_assert(!is_provider_done(auth, PROVIDER_BLACKLIST));
|
lrb_assert(!is_provider_done(auth, SELF_PID));
|
||||||
lrb_assert(rb_dlink_list_length(&blacklist_list) > 0);
|
lrb_assert(rb_dlink_list_length(&blacklist_list) > 0);
|
||||||
|
|
||||||
if(bluser == NULL || rb_dlink_list_length(&bluser->queries))
|
if(bluser == NULL || rb_dlink_list_length(&bluser->queries))
|
||||||
/* Nothing to do */
|
/* Nothing to do */
|
||||||
return;
|
return;
|
||||||
else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)))
|
else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
|
||||||
/* Don't start until we've completed these */
|
(!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;
|
return;
|
||||||
else
|
else
|
||||||
lookup_all_blacklists(auth);
|
lookup_all_blacklists(auth);
|
||||||
|
@ -384,7 +393,7 @@ static void
|
||||||
blacklists_cancel(struct auth_client *auth)
|
blacklists_cancel(struct auth_client *auth)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr, *nptr;
|
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)
|
if(bluser == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -406,9 +415,9 @@ blacklists_cancel(struct auth_client *auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_free(bluser);
|
rb_free(bluser);
|
||||||
set_provider_data(auth, PROVIDER_BLACKLIST, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_BLACKLIST, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
provider_done(auth, PROVIDER_BLACKLIST);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -549,7 +558,8 @@ struct auth_opts_handler blacklist_options[] =
|
||||||
|
|
||||||
struct auth_provider blacklist_provider =
|
struct auth_provider blacklist_provider =
|
||||||
{
|
{
|
||||||
.id = PROVIDER_BLACKLIST,
|
.name = "blacklist",
|
||||||
|
.letter = 'B',
|
||||||
.destroy = blacklists_destroy,
|
.destroy = blacklists_destroy,
|
||||||
.start = blacklists_start,
|
.start = blacklists_start,
|
||||||
.cancel = blacklists_cancel,
|
.cancel = blacklists_cancel,
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "provider.h"
|
#include "provider.h"
|
||||||
#include "res.h"
|
#include "res.h"
|
||||||
|
|
||||||
|
#define SELF_PID (ident_provider.id)
|
||||||
|
|
||||||
#define IDENT_BUFSIZE 128
|
#define IDENT_BUFSIZE 128
|
||||||
|
|
||||||
struct ident_query
|
struct ident_query
|
||||||
|
@ -88,7 +90,7 @@ ident_connected(rb_fde_t *F __unused, int error, void *data)
|
||||||
int authlen;
|
int authlen;
|
||||||
|
|
||||||
lrb_assert(auth != NULL);
|
lrb_assert(auth != NULL);
|
||||||
query = get_provider_data(auth, PROVIDER_IDENT);
|
query = get_provider_data(auth, SELF_PID);
|
||||||
lrb_assert(query != NULL);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
/* Check the error */
|
/* Check the error */
|
||||||
|
@ -125,7 +127,7 @@ read_ident_reply(rb_fde_t *F, void *data)
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
lrb_assert(auth != NULL);
|
lrb_assert(auth != NULL);
|
||||||
query = get_provider_data(auth, PROVIDER_IDENT);
|
query = get_provider_data(auth, SELF_PID);
|
||||||
lrb_assert(query != NULL);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
len = rb_read(F, buf, IDENT_BUFSIZE);
|
len = rb_read(F, buf, IDENT_BUFSIZE);
|
||||||
|
@ -170,7 +172,7 @@ read_ident_reply(rb_fde_t *F, void *data)
|
||||||
static void
|
static void
|
||||||
client_fail(struct auth_client *auth, ident_message report)
|
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);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
|
@ -180,17 +182,17 @@ client_fail(struct auth_client *auth, ident_message report)
|
||||||
rb_close(query->F);
|
rb_close(query->F);
|
||||||
|
|
||||||
rb_free(query);
|
rb_free(query);
|
||||||
set_provider_data(auth, PROVIDER_IDENT, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_IDENT, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
|
|
||||||
notice_client(auth->cid, messages[report]);
|
notice_client(auth->cid, messages[report]);
|
||||||
provider_done(auth, PROVIDER_IDENT);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_success(struct auth_client *auth)
|
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);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
|
@ -198,11 +200,11 @@ client_success(struct auth_client *auth)
|
||||||
rb_close(query->F);
|
rb_close(query->F);
|
||||||
|
|
||||||
rb_free(query);
|
rb_free(query);
|
||||||
set_provider_data(auth, PROVIDER_IDENT, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_IDENT, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
|
|
||||||
notice_client(auth->cid, messages[REPORT_FOUND]);
|
notice_client(auth->cid, messages[REPORT_FOUND]);
|
||||||
provider_done(auth, PROVIDER_IDENT);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get_valid_ident
|
/* get_valid_ident
|
||||||
|
@ -278,7 +280,7 @@ ident_destroy(void)
|
||||||
/* Nuke all ident queries */
|
/* Nuke all ident queries */
|
||||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
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);
|
client_fail(auth, REPORT_FAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,20 +292,20 @@ ident_start(struct auth_client *auth)
|
||||||
struct rb_sockaddr_storage l_addr, c_addr;
|
struct rb_sockaddr_storage l_addr, c_addr;
|
||||||
int family = GET_SS_FAMILY(&auth->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)
|
if(!ident_enable)
|
||||||
{
|
{
|
||||||
rb_free(query);
|
rb_free(query);
|
||||||
notice_client(auth->cid, messages[REPORT_DISABLED]);
|
notice_client(auth->cid, messages[REPORT_DISABLED]);
|
||||||
set_provider_done(auth, PROVIDER_IDENT);
|
set_provider_done(auth, SELF_PID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
||||||
|
|
||||||
set_provider_data(auth, PROVIDER_IDENT, query);
|
set_provider_data(auth, SELF_PID, query);
|
||||||
set_provider_timeout_relative(auth, PROVIDER_IDENT, ident_timeout);
|
set_provider_timeout_relative(auth, SELF_PID, ident_timeout);
|
||||||
|
|
||||||
if((query->F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
|
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,
|
GET_SS_LEN(&l_addr), ident_connected,
|
||||||
auth, ident_timeout);
|
auth, ident_timeout);
|
||||||
|
|
||||||
set_provider_running(auth, PROVIDER_IDENT);
|
set_provider_running(auth, SELF_PID);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +334,7 @@ ident_start(struct auth_client *auth)
|
||||||
static void
|
static void
|
||||||
ident_cancel(struct auth_client *auth)
|
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)
|
if(query != NULL)
|
||||||
client_fail(auth, REPORT_FAIL);
|
client_fail(auth, REPORT_FAIL);
|
||||||
|
@ -368,7 +370,8 @@ struct auth_opts_handler ident_options[] =
|
||||||
|
|
||||||
struct auth_provider ident_provider =
|
struct auth_provider ident_provider =
|
||||||
{
|
{
|
||||||
.id = PROVIDER_IDENT,
|
.name = "ident",
|
||||||
|
.letter = 'I',
|
||||||
.start = ident_start,
|
.start = ident_start,
|
||||||
.destroy = ident_destroy,
|
.destroy = ident_destroy,
|
||||||
.cancel = ident_cancel,
|
.cancel = ident_cancel,
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "notice.h"
|
#include "notice.h"
|
||||||
#include "provider.h"
|
#include "provider.h"
|
||||||
|
|
||||||
|
#define SELF_PID (opm_provider.id)
|
||||||
|
|
||||||
#define OPM_READSIZE 128
|
#define OPM_READSIZE 128
|
||||||
|
|
||||||
typedef enum protocol_t
|
typedef enum protocol_t
|
||||||
|
@ -133,7 +135,7 @@ read_opm_reply(rb_fde_t *F, void *data)
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
lrb_assert(auth != NULL);
|
lrb_assert(auth != NULL);
|
||||||
lookup = get_provider_data(auth, PROVIDER_OPM);
|
lookup = get_provider_data(auth, SELF_PID);
|
||||||
lrb_assert(lookup != NULL);
|
lrb_assert(lookup != NULL);
|
||||||
|
|
||||||
if((len = rb_read(F, readbuf, sizeof(readbuf))) < 0 && rb_ignore_errno(errno))
|
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 */
|
/* No longer needed, client is going away */
|
||||||
rb_free(lookup);
|
rb_free(lookup);
|
||||||
|
|
||||||
reject_client(auth, PROVIDER_OPM, readbuf, "Open proxy detected");
|
reject_client(auth, SELF_PID, readbuf, "Open proxy detected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,7 +262,7 @@ socks4_connected(rb_fde_t *F, int error, void *data)
|
||||||
lrb_assert(scan != NULL);
|
lrb_assert(scan != NULL);
|
||||||
|
|
||||||
auth = scan->auth;
|
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 */
|
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);
|
lrb_assert(scan != NULL);
|
||||||
|
|
||||||
auth = scan->auth;
|
auth = scan->auth;
|
||||||
lookup = get_provider_data(auth, PROVIDER_OPM);
|
lookup = get_provider_data(auth, SELF_PID);
|
||||||
|
|
||||||
/* Build the version header and socks request
|
/* Build the version header and socks request
|
||||||
* version header (3 bytes): version, number of auth methods, auth type (0 for none)
|
* 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);
|
lrb_assert(scan != NULL);
|
||||||
|
|
||||||
auth = scan->auth;
|
auth = scan->auth;
|
||||||
lookup = get_provider_data(auth, PROVIDER_OPM);
|
lookup = get_provider_data(auth, SELF_PID);
|
||||||
|
|
||||||
switch(GET_SS_FAMILY(&auth->c_addr))
|
switch(GET_SS_FAMILY(&auth->c_addr))
|
||||||
{
|
{
|
||||||
|
@ -425,7 +427,7 @@ end:
|
||||||
static inline void
|
static inline void
|
||||||
establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
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_listener *listener;
|
||||||
struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan));
|
struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan));
|
||||||
struct rb_sockaddr_storage c_a, l_a;
|
struct rb_sockaddr_storage c_a, l_a;
|
||||||
|
@ -617,8 +619,8 @@ opm_scan(struct auth_client *auth)
|
||||||
|
|
||||||
lrb_assert(auth != NULL);
|
lrb_assert(auth != NULL);
|
||||||
|
|
||||||
lookup = get_provider_data(auth, PROVIDER_OPM);
|
lookup = get_provider_data(auth, SELF_PID);
|
||||||
set_provider_timeout_relative(auth, PROVIDER_OPM, opm_timeout);
|
set_provider_timeout_relative(auth, SELF_PID, opm_timeout);
|
||||||
|
|
||||||
lookup->in_progress = true;
|
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 */
|
/* This is called every time a provider is completed as long as we are marked not done */
|
||||||
static void
|
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(provider != SELF_PID);
|
||||||
lrb_assert(!is_provider_done(auth, PROVIDER_OPM));
|
lrb_assert(!is_provider_done(auth, SELF_PID));
|
||||||
lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0);
|
lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0);
|
||||||
|
|
||||||
if(lookup == NULL || lookup->in_progress)
|
if(lookup == NULL || lookup->in_progress)
|
||||||
/* Nothing to do */
|
/* Nothing to do */
|
||||||
return;
|
return;
|
||||||
else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)))
|
else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
|
||||||
/* Don't start until we've completed these */
|
(!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;
|
return;
|
||||||
else
|
else
|
||||||
opm_scan(auth);
|
opm_scan(auth);
|
||||||
|
@ -654,7 +658,9 @@ blacklists_initiate(struct auth_client *auth, provider_t provider)
|
||||||
static bool
|
static bool
|
||||||
opm_start(struct auth_client *auth)
|
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)
|
if(!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0)
|
||||||
{
|
{
|
||||||
|
@ -663,20 +669,23 @@ opm_start(struct auth_client *auth)
|
||||||
return true;
|
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))
|
if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
|
||||||
/* This probably can't happen but let's handle this case anyway */
|
(!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);
|
opm_scan(auth);
|
||||||
|
}
|
||||||
|
|
||||||
set_provider_running(auth, PROVIDER_BLACKLIST);
|
set_provider_running(auth, SELF_PID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opm_cancel(struct auth_client *auth)
|
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)
|
if(lookup != NULL)
|
||||||
{
|
{
|
||||||
|
@ -694,9 +703,9 @@ opm_cancel(struct auth_client *auth)
|
||||||
|
|
||||||
rb_free(lookup);
|
rb_free(lookup);
|
||||||
|
|
||||||
set_provider_data(auth, PROVIDER_OPM, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_OPM, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
provider_done(auth, PROVIDER_OPM);
|
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_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
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)
|
if(lookup == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -934,7 +943,8 @@ struct auth_opts_handler opm_options[] =
|
||||||
|
|
||||||
struct auth_provider opm_provider =
|
struct auth_provider opm_provider =
|
||||||
{
|
{
|
||||||
.id = PROVIDER_OPM,
|
.name = "opm",
|
||||||
|
.letter = 'O',
|
||||||
.destroy = opm_destroy,
|
.destroy = opm_destroy,
|
||||||
.start = opm_start,
|
.start = opm_start,
|
||||||
.cancel = opm_cancel,
|
.cancel = opm_cancel,
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "res.h"
|
#include "res.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
|
|
||||||
|
#define SELF_PID (rdns_provider.id)
|
||||||
|
|
||||||
struct user_query
|
struct user_query
|
||||||
{
|
{
|
||||||
struct dns_query *query; /* Pending DNS 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)
|
dns_answer_callback(const char *res, bool status, query_type type, void *data)
|
||||||
{
|
{
|
||||||
struct auth_client *auth = 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);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ dns_answer_callback(const char *res, bool status, query_type type, void *data)
|
||||||
static void
|
static void
|
||||||
client_fail(struct auth_client *auth, dns_message report)
|
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);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
|
@ -85,15 +87,15 @@ client_fail(struct auth_client *auth, dns_message report)
|
||||||
|
|
||||||
rb_free(query);
|
rb_free(query);
|
||||||
|
|
||||||
set_provider_data(auth, PROVIDER_RDNS, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_RDNS, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
provider_done(auth, PROVIDER_RDNS);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_success(struct auth_client *auth)
|
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);
|
lrb_assert(query != NULL);
|
||||||
|
|
||||||
|
@ -102,9 +104,9 @@ client_success(struct auth_client *auth)
|
||||||
|
|
||||||
rb_free(query);
|
rb_free(query);
|
||||||
|
|
||||||
set_provider_data(auth, PROVIDER_RDNS, NULL);
|
set_provider_data(auth, SELF_PID, NULL);
|
||||||
set_provider_timeout_absolute(auth, PROVIDER_RDNS, 0);
|
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||||
provider_done(auth, PROVIDER_RDNS);
|
provider_done(auth, SELF_PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -115,7 +117,7 @@ rdns_destroy(void)
|
||||||
|
|
||||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
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);
|
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));
|
struct user_query *query = rb_malloc(sizeof(struct user_query));
|
||||||
|
|
||||||
set_provider_data(auth, PROVIDER_RDNS, query);
|
set_provider_data(auth, SELF_PID, query);
|
||||||
set_provider_timeout_relative(auth, PROVIDER_RDNS, rdns_timeout);
|
set_provider_timeout_relative(auth, SELF_PID, rdns_timeout);
|
||||||
|
|
||||||
query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth);
|
query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth);
|
||||||
|
|
||||||
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
||||||
set_provider_running(auth, PROVIDER_RDNS);
|
set_provider_running(auth, SELF_PID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rdns_cancel(struct auth_client *auth)
|
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)
|
if(query != NULL)
|
||||||
client_fail(auth, REPORT_FAIL);
|
client_fail(auth, REPORT_FAIL);
|
||||||
|
@ -166,7 +168,8 @@ struct auth_opts_handler rdns_options[] =
|
||||||
|
|
||||||
struct auth_provider rdns_provider =
|
struct auth_provider rdns_provider =
|
||||||
{
|
{
|
||||||
.id = PROVIDER_RDNS,
|
.name = "rdns",
|
||||||
|
.letter = 'R',
|
||||||
.destroy = rdns_destroy,
|
.destroy = rdns_destroy,
|
||||||
.start = rdns_start,
|
.start = rdns_start,
|
||||||
.cancel = rdns_cancel,
|
.cancel = rdns_cancel,
|
||||||
|
|
|
@ -467,7 +467,7 @@ register_local_user(struct Client *client_p, struct Client *source_p)
|
||||||
return CLIENT_EXITED;
|
return CLIENT_EXITED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O': /* OPM */
|
||||||
if(IsExemptKline(source_p) || IsConfExemptProxy(aconf))
|
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",
|
sendto_one_notice(source_p, ":*** Your IP address %s has been detected as an open proxy (ip:port %s), but you are exempt",
|
||||||
|
|
|
@ -704,14 +704,14 @@ rb_dictionary_element *rb_dictionary_add(rb_dictionary *dict, const void *key, v
|
||||||
* - name of DTree node to delete
|
* - name of DTree node to delete
|
||||||
*
|
*
|
||||||
* Outputs:
|
* 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
|
* - on failure, NULL
|
||||||
*
|
*
|
||||||
* Side Effects:
|
* Side Effects:
|
||||||
* - data is removed from the DTree.
|
* - data is removed from the DTree.
|
||||||
*
|
*
|
||||||
* Notes:
|
* 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)
|
void *rb_dictionary_delete(rb_dictionary *dtree, const void *key)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue