From 93be2c584e502e28e9b37da27e308dae33e8960f Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Thu, 29 Jul 2010 08:43:22 +0200 Subject: [PATCH] Reworked plugin APIs slightly, added full support for authentication from plugins. --- src/core/auth.c | 33 ++++--- src/core/auth.h | 10 +- src/core/hub.c | 4 +- src/core/inf.c | 2 +- src/core/plugininvoke.c | 71 +++++++++----- src/core/plugininvoke.h | 2 +- src/core/pluginloader.c | 12 +-- src/core/pluginloader.h | 8 +- src/plugin_api/handle.h | 52 +++++----- src/plugins/mod_auth_simple.c | 173 ++++++++++++++++++++++++---------- src/plugins/mod_example.c | 5 +- src/plugins/mod_logging.c | 12 +-- 12 files changed, 244 insertions(+), 140 deletions(-) diff --git a/src/core/auth.c b/src/core/auth.c index e334e10..fb5be10 100644 --- a/src/core/auth.c +++ b/src/core/auth.c @@ -288,18 +288,29 @@ int acl_shutdown(struct acl_handle* handle) } -struct auth_info* acl_get_access_info(struct acl_handle* handle, const char* name) +struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name) { - struct auth_info* info = (struct auth_info*) list_get_first(handle->users); + struct auth_info* info = 0; +#ifdef PLUGIN_SUPPORT + info = (struct auth_info*) hub_malloc(sizeof(struct auth_info)); + if (plugin_auth_get_user(hub, name, info) != st_allow) + { + hub_free(info); + return NULL; + } + return info; +#else + info = (struct auth_info*) list_get_first(hub->acl->users); while (info) { if (strcasecmp((char*)info->nickname, name) == 0) { return info; } - info = (struct auth_info*) list_get_next(handle->users); + info = (struct auth_info*) list_get_next(hub->acl->users); } return NULL; +#endif } #define STR_LIST_CONTAINS(LIST, STR) \ @@ -411,7 +422,7 @@ int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address) * seconds since the unix epoch (modulus 1 million) * and the SID of the user (0-1 million). */ -const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_user* user) +const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user) { char buf[64]; uint64_t tiger_res[3]; @@ -427,7 +438,7 @@ const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_u } -int acl_password_verify(struct acl_handle* acl, struct hub_user* user, const char* password) +int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password) { char buf[1024]; struct auth_info* access; @@ -440,17 +451,11 @@ int acl_password_verify(struct acl_handle* acl, struct hub_user* user, const cha if (!password || !user || strlen(password) != MAX_CID_LEN) return 0; -#ifdef PLUGIN_SUPPORT - access = (struct auth_info*) hub_malloc(sizeof(struct auth_info)); - if (!plugin_auth_get_user(user->hub, user->id.nick, access)) - return 0; -#else - access = acl_get_access_info(acl, user->id.nick); -#endif - if (!access || !access->password) + access = acl_get_access_info(hub, user->id.nick); + if (!access) return 0; - challenge = acl_password_generate_challenge(acl, user); + challenge = acl_password_generate_challenge(hub, user); base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN); diff --git a/src/core/auth.h b/src/core/auth.h index 842c6f3..978c169 100644 --- a/src/core/auth.h +++ b/src/core/auth.h @@ -21,6 +21,7 @@ #define HAVE_UHUB_ACL_H struct hub_config; +struct hub_info; struct hub_user; struct ip_addr_encap; @@ -38,7 +39,8 @@ struct acl_handle extern int acl_initialize(struct hub_config* config, struct acl_handle* handle); extern int acl_shutdown(struct acl_handle* handle); -extern struct auth_info* acl_get_access_info(struct acl_handle* handle, const char* name); +extern struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name); + extern int acl_is_cid_banned(struct acl_handle* handle, const char* cid); extern int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address); extern int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address); @@ -51,14 +53,14 @@ extern int acl_user_ban_cid(struct acl_handle* handle, const char* cid); extern int acl_user_unban_nick(struct acl_handle* handle, const char* nick); extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid); -extern const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_user* user); - /** * Verify a password. * * @param password the hashed password (based on the nonce). * @return 1 if the password matches, or 0 if the password is incorrect. */ -extern int acl_password_verify(struct acl_handle* acl, struct hub_user* user, const char* password); +extern int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password); +extern const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user); + #endif /* HAVE_UHUB_ACL_H */ diff --git a/src/core/hub.c b/src/core/hub.c index 5a15a35..7a44ed6 100644 --- a/src/core/hub.c +++ b/src/core/hub.c @@ -234,7 +234,7 @@ int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct adc_mes if (u->state == state_verify) { - if (acl_password_verify(hub->acl, u, password)) + if (acl_password_verify(hub, u, password)) { on_login_success(hub, u); } @@ -465,7 +465,7 @@ void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u) { struct adc_message* igpa; igpa = adc_msg_construct(ADC_CMD_IGPA, 38); - adc_msg_add_argument(igpa, acl_password_generate_challenge(hub->acl, u)); + adc_msg_add_argument(igpa, acl_password_generate_challenge(hub, u)); user_set_state(u, state_verify); route_to_user(hub, u, igpa); adc_msg_free(igpa); diff --git a/src/core/inf.c b/src/core/inf.c index 8fe2a15..7b3e08d 100644 --- a/src/core/inf.c +++ b/src/core/inf.c @@ -535,7 +535,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) { int ret = 0; - struct auth_info* info = acl_get_access_info(hub->acl, user->id.nick); + struct auth_info* info = acl_get_access_info(hub, user->id.nick); if (info) { diff --git a/src/core/plugininvoke.c b/src/core/plugininvoke.c index 3a5e7f0..799683a 100644 --- a/src/core/plugininvoke.c +++ b/src/core/plugininvoke.c @@ -20,30 +20,57 @@ #include "uhub.h" #include "plugin_api/handle.h" +#define PLUGIN_DEBUG(hub, name) printf("Invoke %s on %d plugins\n",name, (int) (hub->plugins ? list_size(hub->plugins->loaded) : -1)); + + #define INVOKE(HUB, FUNCNAME, CODE) \ + PLUGIN_DEBUG(HUB, # FUNCNAME) \ if (HUB->plugins && HUB->plugins->loaded) \ { \ - struct uhub_plugin_handle* plugin = (struct uhub_plugin_handle*) list_get_first(HUB->plugins->loaded); \ + struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \ while (plugin) \ { \ if (plugin->funcs.FUNCNAME) \ CODE \ - plugin = (struct uhub_plugin_handle*) list_get_next(HUB->plugins->loaded); \ + plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \ } \ } -#define PLUGIN_INVOKE_STATUS(HUB, FUNCNAME, ARGS) \ +#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \ plugin_st status = st_default; \ INVOKE(HUB, FUNCNAME, { \ - status = plugin->funcs.FUNCNAME ARGS ; \ + status = plugin->funcs.FUNCNAME(plugin, ARG1); \ if (status != st_default) \ break; \ }); \ return status -#define PLUGIN_INVOKE(HUB, FUNCNAME, ARGS) \ +#define PLUGIN_INVOKE_STATUS_2(HUB, FUNCNAME, ARG1, ARG2) \ + plugin_st status = st_default; \ INVOKE(HUB, FUNCNAME, { \ - plugin->funcs.FUNCNAME ARGS ; \ + status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); \ + if (status != st_default) \ + break; \ + }); \ + return status + +#define PLUGIN_INVOKE_STATUS_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) \ + plugin_st status = st_default; \ + INVOKE(HUB, FUNCNAME, { \ + status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); \ + if (status != st_default) \ + break; \ + }); \ + return status + +#define PLUGIN_INVOKE_1(HUB, FUNCNAME, ARG1) \ + INVOKE(HUB, FUNCNAME, { \ + plugin->funcs.FUNCNAME(plugin, ARG1); \ + }) + +#define PLUGIN_INVOKE_2(HUB, FUNCNAME, ARG1, ARG2) \ + INVOKE(HUB, FUNCNAME, { \ + plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); \ }) static void convert_user_type(struct plugin_user* puser, struct hub_user* user) @@ -57,12 +84,12 @@ static void convert_user_type(struct plugin_user* puser, struct hub_user* user) plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr) { - PLUGIN_INVOKE_STATUS(hub, login_check_ip_early, (addr)); + PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_early, addr); } plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr) { - PLUGIN_INVOKE_STATUS(hub, login_check_ip_late, (addr)); + PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_late, addr); } void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* ipaddr) @@ -81,42 +108,42 @@ void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* who) { struct plugin_user user; convert_user_type(&user, who); - PLUGIN_INVOKE(hub, on_user_login, (&user)); + PLUGIN_INVOKE_1(hub, on_user_login, &user); } void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason) { struct plugin_user user; convert_user_type(&user, who); - PLUGIN_INVOKE(hub, on_user_login_error, (&user, reason)); + PLUGIN_INVOKE_2(hub, on_user_login_error, &user, reason); } void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason) { struct plugin_user user; convert_user_type(&user, who); - PLUGIN_INVOKE(hub, on_user_logout, (&user, reason)); + PLUGIN_INVOKE_2(hub, on_user_logout, &user, reason); } void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick) { struct plugin_user user; convert_user_type(&user, who); - PLUGIN_INVOKE(hub, on_user_nick_change, (&user, new_nick)); + PLUGIN_INVOKE_2(hub, on_user_nick_change, &user, new_nick); } void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason) { struct plugin_user user; convert_user_type(&user, who); - PLUGIN_INVOKE(hub, on_user_update_error, (&user, reason)); + PLUGIN_INVOKE_2(hub, on_user_update_error, &user, reason); } plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags) { struct plugin_user user; convert_user_type(&user, from); - PLUGIN_INVOKE_STATUS(hub, on_chat_msg, (&user, message)); + PLUGIN_INVOKE_STATUS_2(hub, on_chat_msg, &user, message); } plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags) @@ -125,14 +152,14 @@ plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* f struct plugin_user user2; convert_user_type(&user1, from); convert_user_type(&user2, to); - PLUGIN_INVOKE_STATUS(hub, on_private_msg, (&user1, &user2, message)); + PLUGIN_INVOKE_STATUS_3(hub, on_private_msg, &user1, &user2, message); } plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data) { struct plugin_user user; convert_user_type(&user, from); - PLUGIN_INVOKE_STATUS(hub, on_search, (&user, data)); + PLUGIN_INVOKE_STATUS_2(hub, on_search, &user, data); } plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to) @@ -141,7 +168,7 @@ plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, str struct plugin_user user2; convert_user_type(&user1, from); convert_user_type(&user2, to); - PLUGIN_INVOKE_STATUS(hub, on_p2p_connect, (&user1, &user2)); + PLUGIN_INVOKE_STATUS_2(hub, on_p2p_connect, &user1, &user2); } plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to) @@ -150,25 +177,25 @@ plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct plugin_user user2; convert_user_type(&user1, from); convert_user_type(&user2, to); - PLUGIN_INVOKE_STATUS(hub, on_p2p_revconnect, (&user1, &user2)); + PLUGIN_INVOKE_STATUS_2(hub, on_p2p_revconnect, &user1, &user2); } plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info) { - PLUGIN_INVOKE_STATUS(hub, auth_get_user, (nickname, info)); + PLUGIN_INVOKE_STATUS_2(hub, auth_get_user, nickname, info); } plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* info) { - PLUGIN_INVOKE_STATUS(hub, auth_register_user, (info)); + PLUGIN_INVOKE_STATUS_1(hub, auth_register_user, info); } plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* info) { - PLUGIN_INVOKE_STATUS(hub, auth_update_user, (info)); + PLUGIN_INVOKE_STATUS_1(hub, auth_update_user, info); } plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* info) { - PLUGIN_INVOKE_STATUS(hub, auth_delete_user, (info)); + PLUGIN_INVOKE_STATUS_1(hub, auth_delete_user, info); } diff --git a/src/core/plugininvoke.h b/src/core/plugininvoke.h index 6291b0f..ec968a8 100644 --- a/src/core/plugininvoke.h +++ b/src/core/plugininvoke.h @@ -54,7 +54,7 @@ plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, str plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to); /* Authentication related */ -int plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info); +plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info); plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* user); plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* user); plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* user); diff --git a/src/core/pluginloader.c b/src/core/pluginloader.c index 5af3e57..51995d7 100644 --- a/src/core/pluginloader.c +++ b/src/core/pluginloader.c @@ -65,12 +65,12 @@ void* plugin_lookup_symbol(struct uhub_plugin* plugin, const char* symbol) #endif } -struct uhub_plugin_handle* plugin_load(const char* filename, const char* config) +struct plugin_handle* plugin_load(const char* filename, const char* config) { plugin_register_f register_f; plugin_unregister_f unregister_f; int ret; - struct uhub_plugin_handle* handle = hub_malloc_zero(sizeof(struct uhub_plugin_handle)); + struct plugin_handle* handle = hub_malloc_zero(sizeof(struct plugin_handle)); struct uhub_plugin* plugin = plugin_open(filename); if (!plugin) @@ -114,7 +114,7 @@ struct uhub_plugin_handle* plugin_load(const char* filename, const char* config) return NULL; } -void plugin_unload(struct uhub_plugin_handle* plugin) +void plugin_unload(struct plugin_handle* plugin) { plugin->handle->unregister(plugin); plugin_close(plugin->handle); @@ -148,7 +148,7 @@ static int plugin_parse_line(char* line, int line_count, void* ptr_data) params = ""; LOG_TRACE("Load plugin: \"%s\", params=\"%s\"", soname, params); - struct uhub_plugin_handle* plugin = plugin_load(soname, params); + struct plugin_handle* plugin = plugin_load(soname, params); if (plugin) { list_append(handle->loaded, plugin); @@ -183,12 +183,12 @@ int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle) void plugin_shutdown(struct uhub_plugins* handle) { - struct uhub_plugin_handle* plugin = (struct uhub_plugin_handle*) list_get_first(handle->loaded); + struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded); while (plugin) { list_remove(handle->loaded, plugin); plugin_unload(plugin); - plugin = (struct uhub_plugin_handle*) list_get_first(handle->loaded); + plugin = (struct plugin_handle*) list_get_first(handle->loaded); } list_destroy(handle->loaded); diff --git a/src/core/pluginloader.h b/src/core/pluginloader.h index e5d6bf5..cf5206e 100644 --- a/src/core/pluginloader.h +++ b/src/core/pluginloader.h @@ -26,7 +26,7 @@ struct hub_config; struct linked_list; -struct uhub_plugin_handle; +struct plugin_handle; struct uhub_plugin { @@ -42,10 +42,10 @@ struct uhub_plugins }; // High level plugin loader ode -extern struct uhub_plugin_handle* plugin_load(const char* filename, const char* config); -extern void plugin_unload(struct uhub_plugin_handle* plugin); +extern struct plugin_handle* plugin_load(const char* filename, const char* config); +extern void plugin_unload(struct plugin_handle* plugin); -// extern void plugin_unload(struct uhub_plugin_handle*); +// extern void plugin_unload(struct plugin_handle*); extern int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle); extern void plugin_shutdown(struct uhub_plugins* handle); diff --git a/src/plugin_api/handle.h b/src/plugin_api/handle.h index 27cb4af..f9e5d1f 100644 --- a/src/plugin_api/handle.h +++ b/src/plugin_api/handle.h @@ -34,6 +34,8 @@ #define MAX_PASS_LEN 64 #endif +struct plugin_handle; + struct plugin_user { unsigned int sid; @@ -59,30 +61,30 @@ struct auth_info enum auth_credentials credentials; }; -typedef plugin_st (*on_chat_msg_t)(struct plugin_user* from, const char* message); -typedef plugin_st (*on_private_msg_t)(struct plugin_user* from, struct plugin_user* to, const char* message); -typedef plugin_st (*on_search_t)(struct plugin_user* from, const char* data); -typedef plugin_st (*on_p2p_connect_t)(struct plugin_user* from, struct plugin_user* to); -typedef plugin_st (*on_p2p_revconnect_t)(struct plugin_user* from, struct plugin_user* to); +typedef plugin_st (*on_chat_msg_t)(struct plugin_handle*, struct plugin_user* from, const char* message); +typedef plugin_st (*on_private_msg_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to, const char* message); +typedef plugin_st (*on_search_t)(struct plugin_handle*, struct plugin_user* from, const char* data); +typedef plugin_st (*on_p2p_connect_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to); +typedef plugin_st (*on_p2p_revconnect_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to); -typedef void (*on_user_connect_t)(struct ip_addr_encap*); -typedef void (*on_user_login_t)(struct plugin_user*); -typedef void (*on_user_login_error_t)(struct plugin_user*, const char* reason); -typedef void (*on_user_logout_t)(struct plugin_user*, const char* reason); -typedef void (*on_user_nick_change_t)(struct plugin_user*, const char* new_nick); -typedef void (*on_user_update_error_t)(struct plugin_user*, const char* reason); +typedef void (*on_user_connect_t)(struct plugin_handle*, struct ip_addr_encap*); +typedef void (*on_user_login_t)(struct plugin_handle*, struct plugin_user*); +typedef void (*on_user_login_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason); +typedef void (*on_user_logout_t)(struct plugin_handle*, struct plugin_user*, const char* reason); +typedef void (*on_user_nick_change_t)(struct plugin_handle*, struct plugin_user*, const char* new_nick); +typedef void (*on_user_update_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason); -typedef plugin_st (*on_change_nick_t)(struct plugin_user*, const char* new_nick); +typedef plugin_st (*on_change_nick_t)(struct plugin_handle*, struct plugin_user*, const char* new_nick); -typedef plugin_st (*on_check_ip_early_t)(struct ip_addr_encap*); -typedef plugin_st (*on_check_ip_late_t)(struct ip_addr_encap*); -typedef plugin_st (*on_validate_nick_t)(const char* nick); -typedef plugin_st (*on_validate_cid_t)(const char* cid); +typedef plugin_st (*on_check_ip_early_t)(struct plugin_handle*, struct ip_addr_encap*); +typedef plugin_st (*on_check_ip_late_t)(struct plugin_handle*, struct ip_addr_encap*); +typedef plugin_st (*on_validate_nick_t)(struct plugin_handle*, const char* nick); +typedef plugin_st (*on_validate_cid_t)(struct plugin_handle*, const char* cid); -typedef plugin_st (*auth_get_user_t)(const char* nickname, struct auth_info* info); -typedef plugin_st (*auth_register_user_t)(struct auth_info* user); -typedef plugin_st (*auth_update_user_t)(struct auth_info* user); -typedef plugin_st (*auth_delete_user_t)(struct auth_info* user); +typedef plugin_st (*auth_get_user_t)(struct plugin_handle*, const char* nickname, struct auth_info* info); +typedef plugin_st (*auth_register_user_t)(struct plugin_handle*, struct auth_info* user); +typedef plugin_st (*auth_update_user_t)(struct plugin_handle*, struct auth_info* user); +typedef plugin_st (*auth_delete_user_t)(struct plugin_handle*, struct auth_info* user); struct plugin_funcs { @@ -113,7 +115,7 @@ struct plugin_funcs }; -struct uhub_plugin_handle +struct plugin_handle { struct uhub_plugin* handle; /* Must NOT be modified by the plugin */ const char* name; /* plugin name */ @@ -133,14 +135,14 @@ struct uhub_plugin_handle * @param config A configuration string * @return 0 on success, -1 on error. */ -extern int plugin_register(struct uhub_plugin_handle* handle, const char* config); +extern int plugin_register(struct plugin_handle* handle, const char* config); /** * @return 0 on success, -1 on error. */ -extern int plugin_unregister(struct uhub_plugin_handle*); +extern int plugin_unregister(struct plugin_handle*); -typedef int (*plugin_register_f)(struct uhub_plugin_handle* handle, const char* config); -typedef int (*plugin_unregister_f)(struct uhub_plugin_handle*); +typedef int (*plugin_register_f)(struct plugin_handle* handle, const char* config); +typedef int (*plugin_unregister_f)(struct plugin_handle*); #endif /* HAVE_UHUB_PLUGIN_HANDLE_H */ diff --git a/src/plugins/mod_auth_simple.c b/src/plugins/mod_auth_simple.c index 8fe3eee..3fcaa05 100644 --- a/src/plugins/mod_auth_simple.c +++ b/src/plugins/mod_auth_simple.c @@ -11,17 +11,20 @@ #include "util/log.h" #include "util/config_token.h" -static void set_error_message(struct uhub_plugin_handle* plugin, const char* msg) +static void set_error_message(struct plugin_handle* plugin, const char* msg) { plugin->error_msg = msg; } -struct acl_list +struct acl_data { struct linked_list* users; + char* file; + int readonly; + int exclusive; }; -void insert_user(struct linked_list* users, const char* nick, const char* pass, enum auth_credentials cred) +static void insert_user(struct linked_list* users, const char* nick, const char* pass, enum auth_credentials cred) { struct auth_info* data = (struct auth_info*) hub_malloc_zero(sizeof(struct auth_info)); strncpy(data->nickname, nick, MAX_NICK_LEN); @@ -30,6 +33,69 @@ void insert_user(struct linked_list* users, const char* nick, const char* pass, list_append(users, data); } +static void free_acl(struct acl_data* data) +{ + if (!data) + return; + + if (data->users) + { + list_clear(data->users, hub_free); + list_destroy(data->users); + } + hub_free(data->file); + hub_free(data); +} + +static struct acl_data* parse_config(const char* line) +{ + struct acl_data* data = (struct acl_data*) hub_malloc_zero(sizeof(struct acl_data)); + struct cfg_tokens* tokens = cfg_tokenize(line); + char* token = cfg_token_get_first(tokens); + + if (!data) + return 0; + + // set defaults + data->readonly = 1; + data->exclusive = 0; + data->users = list_create(); + + while (token) + { + char* split = strchr(token, '='); + size_t len = strlen(token); + size_t key = split ? (split - token) : len; + if (key == 4 && strncmp(token, "file", 4) == 0) + { + if (data->file) + hub_free(data->file); + data->file = strdup(split + 1); + } + else if (key == 8 && strncmp(token, "readonly", 8) == 0) + { + if (!string_to_boolean(split + 1, &data->readonly)) + data->readonly = 1; + } + else if (key == 9 && strncmp(token, "exclusive", 9) == 0) + { + if (!string_to_boolean(split + 1, &data->exclusive)) + data->exclusive = 1; + } + else + { + cfg_tokens_free(tokens); + free_acl(data); + return 0; + } + + token = cfg_token_get_next(tokens); + } + + cfg_tokens_free(tokens); + return data; +} + static int parse_line(char* line, int line_count, void* ptr_data) { struct linked_list* users = (struct linked_list*) ptr_data; @@ -48,8 +114,8 @@ static int parse_line(char* line, int line_count, void* ptr_data) if (strcmp(credential, "admin")) cred = auth_cred_admin; else if (strcmp(credential, "super")) cred = auth_cred_super; - else if (strcmp(credential, "op")) cred = auth_cred_operator; - else if (strcmp(credential, "reg")) cred = auth_cred_user; + else if (strcmp(credential, "op")) cred = auth_cred_operator; + else if (strcmp(credential, "reg")) cred = auth_cred_user; else return -1; @@ -58,79 +124,82 @@ static int parse_line(char* line, int line_count, void* ptr_data) return 0; } - -static struct acl_list* load_acl(const char* filename, struct uhub_plugin_handle* handle) +static struct acl_data* load_acl(const char* config, struct plugin_handle* handle) { - struct acl_list* list = (struct acl_list*) hub_malloc(sizeof(struct acl_list)); - struct linked_list* users = list_create(); - if (!list || !users) + struct acl_data* data = parse_config(config); + + if (!data) + return 0; + + if (!data->file || !*data->file) { - list_destroy(users); - hub_free(list); - set_error_message(handle, "Unable to allocate memory"); + free_acl(data); data = 0; + set_error_message(handle, "No configuration file given, missing \"file=\" configuration option."); return 0; } - if (!filename || !*filename) + if (file_read_lines(data->file, data->users, &parse_line) == -1) { - list_destroy(users); - hub_free(list); - set_error_message(handle, "No configuration file given"); - return 0; + fprintf(stderr, "Unable to load %s\n", data->file); + set_error_message(handle, "Unable to load file"); } - if (users) + return data; +} + +static void unload_acl(struct acl_data* data) +{ + free_acl(data); +} + +static plugin_st get_user(struct plugin_handle* plugin, const char* nickname, struct auth_info* data) +{ + struct acl_data* acl = (struct acl_data*) plugin->ptr; + struct auth_info* info = (struct auth_info*) list_get_first(acl->users); + while (info) { - if (file_read_lines(filename, users, &parse_line) == -1) + if (strcasecmp((char*)info->nickname, nickname) == 0) { - fprintf(stderr, "Unable to load %s\n", filename); - set_error_message(handle, "Unable to load file"); + memcpy(data, info, sizeof(struct auth_info)); + return st_allow; } + info = (struct auth_info*) list_get_next(acl->users); } - - list->users = users; - return list; + if (acl->exclusive) + return st_deny; + return st_default; } -static void unload_acl(struct acl_list* list) +static plugin_st register_user(struct plugin_handle* plugin, struct auth_info* user) { - if (!list) - return; - - list_clear(list->users, hub_free); - list_destroy(list->users); - hub_free(list); + struct acl_data* acl = (struct acl_data*) plugin->ptr; + if (acl->exclusive) + return st_deny; + return st_default; } -static int get_user(const char* nickname, struct auth_info* info) +static plugin_st update_user(struct plugin_handle* plugin, struct auth_info* user) { - return 0; + struct acl_data* acl = (struct acl_data*) plugin->ptr; + if (acl->exclusive) + return st_deny; + return st_default; } -static plugin_st register_user(struct auth_info* user) +static plugin_st delete_user(struct plugin_handle* plugin, struct auth_info* user) { - /* Read only mode - so rejected */ - return st_deny; + struct acl_data* acl = (struct acl_data*) plugin->ptr; + if (acl->exclusive) + return st_deny; + return st_default; } -static plugin_st update_user(struct auth_info* user) -{ - /* Read only mode - so rejected */ - return st_deny; -} - -static plugin_st delete_user(struct auth_info* user) -{ - /* Read only mode - so rejected */ - return st_deny; -} - -int plugin_register(struct uhub_plugin_handle* plugin, const char* config) +int plugin_register(struct plugin_handle* plugin, const char* config) { plugin->name = "File authentication plugin"; plugin->version = "0.1"; - plugin->description = "Authenticated users based on a read-only text file."; + plugin->description = "Authenticate users based on a read-only text file."; plugin->plugin_api_version = PLUGIN_API_VERSION; plugin->plugin_funcs_size = sizeof(struct plugin_funcs); memset(&plugin->funcs, 0, sizeof(struct plugin_funcs)); @@ -147,7 +216,7 @@ int plugin_register(struct uhub_plugin_handle* plugin, const char* config) return -1; } -int plugin_unregister(struct uhub_plugin_handle* plugin) +int plugin_unregister(struct plugin_handle* plugin) { set_error_message(plugin, 0); unload_acl(plugin->ptr); diff --git a/src/plugins/mod_example.c b/src/plugins/mod_example.c index 97406ae..865ac23 100644 --- a/src/plugins/mod_example.c +++ b/src/plugins/mod_example.c @@ -2,10 +2,9 @@ * This is a minimal example plugin for uhub. */ -// #include "uhub.h" #include "plugin_api/handle.h" -int plugin_register(struct uhub_plugin_handle* plugin, const char* config) +int plugin_register(struct plugin_handle* plugin, const char* config) { plugin->name = "Example plugin"; plugin->version = "1.0"; @@ -19,7 +18,7 @@ int plugin_register(struct uhub_plugin_handle* plugin, const char* config) return 0; } -int plugin_unregister(struct uhub_plugin_handle* plugin) +int plugin_unregister(struct plugin_handle* plugin) { /* No need to do anything! */ puts("plugin unregister"); diff --git a/src/plugins/mod_logging.c b/src/plugins/mod_logging.c index 1ae315f..e667ae6 100644 --- a/src/plugins/mod_logging.c +++ b/src/plugins/mod_logging.c @@ -7,29 +7,29 @@ struct ip_addr_encap; -plugin_st log_connect(struct ip_addr_encap* addr) +plugin_st log_connect(struct plugin_handle* plugin, struct ip_addr_encap* addr) { return st_default; } -void log_user_login(struct plugin_user* user) +void log_user_login(struct plugin_handle* plugin, struct plugin_user* user) { printf("login: \"%s\"\n", user->nick); } -void log_user_logout(struct plugin_user* user) +void log_user_logout(struct plugin_handle* plugin, struct plugin_user* user) { printf("logout: \"%s\"\n", user->nick); } -plugin_st log_change_nick(struct plugin_user* user, const char* new_nick) +plugin_st log_change_nick(struct plugin_handle* plugin, struct plugin_user* user, const char* new_nick) { printf("\"%s\" -> \"%s\"\n", user->nick, new_nick); return st_default; } -int plugin_register(struct uhub_plugin_handle* plugin, const char* config) +int plugin_register(struct plugin_handle* plugin, const char* config) { plugin->name = "Logging plugin"; plugin->version = "1.0"; @@ -48,7 +48,7 @@ int plugin_register(struct uhub_plugin_handle* plugin, const char* config) return 0; } -int plugin_unregister(struct uhub_plugin_handle* plugin) +int plugin_unregister(struct plugin_handle* plugin) { /* No need to do anything! */ puts("* plugin unregister");