Reworked plugin APIs slightly, added full support for authentication from plugins.

This commit is contained in:
Jan Vidar Krey 2010-07-29 08:43:22 +02:00
parent c75090cdf2
commit 93be2c584e
12 changed files with 244 additions and 140 deletions

View File

@ -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) while (info)
{ {
if (strcasecmp((char*)info->nickname, name) == 0) if (strcasecmp((char*)info->nickname, name) == 0)
{ {
return info; return info;
} }
info = (struct auth_info*) list_get_next(handle->users); info = (struct auth_info*) list_get_next(hub->acl->users);
} }
return NULL; return NULL;
#endif
} }
#define STR_LIST_CONTAINS(LIST, STR) \ #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) * seconds since the unix epoch (modulus 1 million)
* and the SID of the user (0-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]; char buf[64];
uint64_t tiger_res[3]; 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]; char buf[1024];
struct auth_info* access; 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) if (!password || !user || strlen(password) != MAX_CID_LEN)
return 0; return 0;
#ifdef PLUGIN_SUPPORT access = acl_get_access_info(hub, user->id.nick);
access = (struct auth_info*) hub_malloc(sizeof(struct auth_info)); if (!access)
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)
return 0; 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); base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);

View File

@ -21,6 +21,7 @@
#define HAVE_UHUB_ACL_H #define HAVE_UHUB_ACL_H
struct hub_config; struct hub_config;
struct hub_info;
struct hub_user; struct hub_user;
struct ip_addr_encap; 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_initialize(struct hub_config* config, struct acl_handle* handle);
extern int acl_shutdown(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_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_banned(struct acl_handle* handle, const char* ip_address);
extern int acl_is_ip_nat_override(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_nick(struct acl_handle* handle, const char* nick);
extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid); 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. * Verify a password.
* *
* @param password the hashed password (based on the nonce). * @param password the hashed password (based on the nonce).
* @return 1 if the password matches, or 0 if the password is incorrect. * @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 */ #endif /* HAVE_UHUB_ACL_H */

View File

@ -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 (u->state == state_verify)
{ {
if (acl_password_verify(hub->acl, u, password)) if (acl_password_verify(hub, u, password))
{ {
on_login_success(hub, u); 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; struct adc_message* igpa;
igpa = adc_msg_construct(ADC_CMD_IGPA, 38); 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); user_set_state(u, state_verify);
route_to_user(hub, u, igpa); route_to_user(hub, u, igpa);
adc_msg_free(igpa); adc_msg_free(igpa);

View File

@ -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) static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{ {
int ret = 0; 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) if (info)
{ {

View File

@ -20,30 +20,57 @@
#include "uhub.h" #include "uhub.h"
#include "plugin_api/handle.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) \ #define INVOKE(HUB, FUNCNAME, CODE) \
PLUGIN_DEBUG(HUB, # FUNCNAME) \
if (HUB->plugins && HUB->plugins->loaded) \ 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) \ while (plugin) \
{ \ { \
if (plugin->funcs.FUNCNAME) \ if (plugin->funcs.FUNCNAME) \
CODE \ 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; \ plugin_st status = st_default; \
INVOKE(HUB, FUNCNAME, { \ INVOKE(HUB, FUNCNAME, { \
status = plugin->funcs.FUNCNAME ARGS ; \ status = plugin->funcs.FUNCNAME(plugin, ARG1); \
if (status != st_default) \ if (status != st_default) \
break; \ break; \
}); \ }); \
return status 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, { \ 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) 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_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_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) 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; struct plugin_user user;
convert_user_type(&user, who); 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) void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, who); 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) void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, who); 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) void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, who); 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) void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, who); 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) plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, from); 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) 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; struct plugin_user user2;
convert_user_type(&user1, from); convert_user_type(&user1, from);
convert_user_type(&user2, to); 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) plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data)
{ {
struct plugin_user user; struct plugin_user user;
convert_user_type(&user, from); 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) 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; struct plugin_user user2;
convert_user_type(&user1, from); convert_user_type(&user1, from);
convert_user_type(&user2, to); 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) 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; struct plugin_user user2;
convert_user_type(&user1, from); convert_user_type(&user1, from);
convert_user_type(&user2, to); 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_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_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_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_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);
} }

View File

@ -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); plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to);
/* Authentication related */ /* 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_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_update_user(struct hub_info* hub, struct auth_info* user);
plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* user); plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* user);

View File

@ -65,12 +65,12 @@ void* plugin_lookup_symbol(struct uhub_plugin* plugin, const char* symbol)
#endif #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_register_f register_f;
plugin_unregister_f unregister_f; plugin_unregister_f unregister_f;
int ret; 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); struct uhub_plugin* plugin = plugin_open(filename);
if (!plugin) if (!plugin)
@ -114,7 +114,7 @@ struct uhub_plugin_handle* plugin_load(const char* filename, const char* config)
return NULL; return NULL;
} }
void plugin_unload(struct uhub_plugin_handle* plugin) void plugin_unload(struct plugin_handle* plugin)
{ {
plugin->handle->unregister(plugin); plugin->handle->unregister(plugin);
plugin_close(plugin->handle); plugin_close(plugin->handle);
@ -148,7 +148,7 @@ static int plugin_parse_line(char* line, int line_count, void* ptr_data)
params = ""; params = "";
LOG_TRACE("Load plugin: \"%s\", params=\"%s\"", soname, 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) if (plugin)
{ {
list_append(handle->loaded, 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) 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) while (plugin)
{ {
list_remove(handle->loaded, plugin); list_remove(handle->loaded, plugin);
plugin_unload(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); list_destroy(handle->loaded);

View File

@ -26,7 +26,7 @@
struct hub_config; struct hub_config;
struct linked_list; struct linked_list;
struct uhub_plugin_handle; struct plugin_handle;
struct uhub_plugin struct uhub_plugin
{ {
@ -42,10 +42,10 @@ struct uhub_plugins
}; };
// High level plugin loader ode // High level plugin loader ode
extern struct uhub_plugin_handle* plugin_load(const char* filename, const char* config); extern struct plugin_handle* plugin_load(const char* filename, const char* config);
extern void plugin_unload(struct uhub_plugin_handle* plugin); 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 int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle);
extern void plugin_shutdown(struct uhub_plugins* handle); extern void plugin_shutdown(struct uhub_plugins* handle);

View File

@ -34,6 +34,8 @@
#define MAX_PASS_LEN 64 #define MAX_PASS_LEN 64
#endif #endif
struct plugin_handle;
struct plugin_user struct plugin_user
{ {
unsigned int sid; unsigned int sid;
@ -59,30 +61,30 @@ struct auth_info
enum auth_credentials credentials; enum auth_credentials credentials;
}; };
typedef plugin_st (*on_chat_msg_t)(struct plugin_user* from, const char* message); 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_user* from, struct plugin_user* to, 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_user* from, const char* data); 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_user* from, struct plugin_user* to); 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_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_connect_t)(struct plugin_handle*, struct ip_addr_encap*);
typedef void (*on_user_login_t)(struct plugin_user*); typedef void (*on_user_login_t)(struct plugin_handle*, struct plugin_user*);
typedef void (*on_user_login_error_t)(struct plugin_user*, const char* reason); typedef void (*on_user_login_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason);
typedef void (*on_user_logout_t)(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_user*, const char* new_nick); 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_user*, const char* reason); 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_early_t)(struct plugin_handle*, struct ip_addr_encap*);
typedef plugin_st (*on_check_ip_late_t)(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)(const char* nick); typedef plugin_st (*on_validate_nick_t)(struct plugin_handle*, const char* nick);
typedef plugin_st (*on_validate_cid_t)(const char* cid); 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_get_user_t)(struct plugin_handle*, const char* nickname, struct auth_info* info);
typedef plugin_st (*auth_register_user_t)(struct auth_info* user); typedef plugin_st (*auth_register_user_t)(struct plugin_handle*, struct auth_info* user);
typedef plugin_st (*auth_update_user_t)(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 auth_info* user); typedef plugin_st (*auth_delete_user_t)(struct plugin_handle*, struct auth_info* user);
struct plugin_funcs 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 */ struct uhub_plugin* handle; /* Must NOT be modified by the plugin */
const char* name; /* plugin name */ const char* name; /* plugin name */
@ -133,14 +135,14 @@ struct uhub_plugin_handle
* @param config A configuration string * @param config A configuration string
* @return 0 on success, -1 on error. * @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. * @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_register_f)(struct plugin_handle* handle, const char* config);
typedef int (*plugin_unregister_f)(struct uhub_plugin_handle*); typedef int (*plugin_unregister_f)(struct plugin_handle*);
#endif /* HAVE_UHUB_PLUGIN_HANDLE_H */ #endif /* HAVE_UHUB_PLUGIN_HANDLE_H */

View File

@ -11,17 +11,20 @@
#include "util/log.h" #include "util/log.h"
#include "util/config_token.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; plugin->error_msg = msg;
} }
struct acl_list struct acl_data
{ {
struct linked_list* users; 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)); struct auth_info* data = (struct auth_info*) hub_malloc_zero(sizeof(struct auth_info));
strncpy(data->nickname, nick, MAX_NICK_LEN); 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); 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) static int parse_line(char* line, int line_count, void* ptr_data)
{ {
struct linked_list* users = (struct linked_list*) 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; if (strcmp(credential, "admin")) cred = auth_cred_admin;
else if (strcmp(credential, "super")) cred = auth_cred_super; else if (strcmp(credential, "super")) cred = auth_cred_super;
else if (strcmp(credential, "op")) cred = auth_cred_operator; else if (strcmp(credential, "op")) cred = auth_cred_operator;
else if (strcmp(credential, "reg")) cred = auth_cred_user; else if (strcmp(credential, "reg")) cred = auth_cred_user;
else else
return -1; return -1;
@ -58,79 +124,82 @@ static int parse_line(char* line, int line_count, void* ptr_data)
return 0; return 0;
} }
static struct acl_data* load_acl(const char* config, struct plugin_handle* handle)
static struct acl_list* load_acl(const char* filename, struct uhub_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); free_acl(data); data = 0;
hub_free(list); set_error_message(handle, "No configuration file given, missing \"file=<filename>\" configuration option.");
set_error_message(handle, "Unable to allocate memory");
return 0; return 0;
} }
if (!filename || !*filename) if (file_read_lines(data->file, data->users, &parse_line) == -1)
{ {
list_destroy(users); fprintf(stderr, "Unable to load %s\n", data->file);
hub_free(list); set_error_message(handle, "Unable to load file");
set_error_message(handle, "No configuration file given");
return 0;
} }
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); memcpy(data, info, sizeof(struct auth_info));
set_error_message(handle, "Unable to load file"); return st_allow;
} }
info = (struct auth_info*) list_get_next(acl->users);
} }
if (acl->exclusive)
list->users = users; return st_deny;
return list; 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) struct acl_data* acl = (struct acl_data*) plugin->ptr;
return; if (acl->exclusive)
return st_deny;
list_clear(list->users, hub_free); return st_default;
list_destroy(list->users);
hub_free(list);
} }
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 */ struct acl_data* acl = (struct acl_data*) plugin->ptr;
return st_deny; if (acl->exclusive)
return st_deny;
return st_default;
} }
static plugin_st update_user(struct auth_info* user) int plugin_register(struct plugin_handle* plugin, const char* config)
{
/* 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)
{ {
plugin->name = "File authentication plugin"; plugin->name = "File authentication plugin";
plugin->version = "0.1"; 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_api_version = PLUGIN_API_VERSION;
plugin->plugin_funcs_size = sizeof(struct plugin_funcs); plugin->plugin_funcs_size = sizeof(struct plugin_funcs);
memset(&plugin->funcs, 0, 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; return -1;
} }
int plugin_unregister(struct uhub_plugin_handle* plugin) int plugin_unregister(struct plugin_handle* plugin)
{ {
set_error_message(plugin, 0); set_error_message(plugin, 0);
unload_acl(plugin->ptr); unload_acl(plugin->ptr);

View File

@ -2,10 +2,9 @@
* This is a minimal example plugin for uhub. * This is a minimal example plugin for uhub.
*/ */
// #include "uhub.h"
#include "plugin_api/handle.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->name = "Example plugin";
plugin->version = "1.0"; plugin->version = "1.0";
@ -19,7 +18,7 @@ int plugin_register(struct uhub_plugin_handle* plugin, const char* config)
return 0; return 0;
} }
int plugin_unregister(struct uhub_plugin_handle* plugin) int plugin_unregister(struct plugin_handle* plugin)
{ {
/* No need to do anything! */ /* No need to do anything! */
puts("plugin unregister"); puts("plugin unregister");

View File

@ -7,29 +7,29 @@
struct ip_addr_encap; 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; 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); 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); 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); printf("\"%s\" -> \"%s\"\n", user->nick, new_nick);
return st_default; 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->name = "Logging plugin";
plugin->version = "1.0"; plugin->version = "1.0";
@ -48,7 +48,7 @@ int plugin_register(struct uhub_plugin_handle* plugin, const char* config)
return 0; return 0;
} }
int plugin_unregister(struct uhub_plugin_handle* plugin) int plugin_unregister(struct plugin_handle* plugin)
{ {
/* No need to do anything! */ /* No need to do anything! */
puts("* plugin unregister"); puts("* plugin unregister");