diff --git a/src/main.c b/src/main.c index c1b0081b..3a57c958 100644 --- a/src/main.c +++ b/src/main.c @@ -110,6 +110,7 @@ CONFIG config; /**< Main configuration structure, as read from configfile */ static void usage(char *program); static void txt_add(char *txtrecord, char *fmt, ...); static void main_handler(WS_CONNINFO *pwsc); +static int main_auth(WS_CONNINFO *pwsc, char *username, char *password); /** * build a dns text string @@ -144,6 +145,15 @@ void main_handler(WS_CONNINFO *pwsc) { config_handler(pwsc); } +int main_auth(WS_CONNINFO *pwsc, char *username, char *password) { + if(plugin_url_candispatch(pwsc)) { + DPRINTF(E_DBG,L_MAIN,"Dispatching auth for %s to plugin\n",pwsc->uri); + return plugin_auth_handle(pwsc,username,password); + } + + DPRINTF(E_DBG,L_MAIN,"Dispatching auth for %s to config auth\n",pwsc->uri); + return config_auth(pwsc, username, password); +} /** @@ -404,7 +414,7 @@ int main(int argc, char *argv[]) { DPRINTF(E_FATAL,L_MAIN|L_WS,"Error staring web server: %s\n",strerror(errno)); } - ws_registerhandler(config.server, "^.*$",main_handler,config_auth,1); + ws_registerhandler(config.server, "^.*$",main_handler,main_auth,1); ws_registerhandler(config.server, "^/server-info$",daap_handler,NULL,0); ws_registerhandler(config.server, "^/content-codes$",daap_handler,daap_auth,0); /* iTunes 6.0.4+? */ ws_registerhandler(config.server,"^/login$",daap_handler,daap_auth,0); diff --git a/src/plugin.c b/src/plugin.c index 8fd4c83f..32af310a 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -267,6 +267,50 @@ void plugin_url_handle(WS_CONNINFO *pwsc) { return; } +/** + * Test password for the handled namespace + * + * @param pwsc the connection info (including uri) to check + * @param username user attempting to login + * @param pw password attempting + * @returns TRUE if we want to handle it + */ +int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) { + PLUGIN_ENTRY *ppi; + int (*auth_fn)(WS_CONNINFO *pwsc, char *username, char *pw); + int result; + + _plugin_readlock(); + ppi = _plugin_list.next; + while(ppi) { + if(ppi->type == PLUGIN_OUTPUT) { + if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) { + /* we have a winner */ + DPRINTF(E_DBG,L_PLUG,"Dispatching %s to %s\n", pwsc->uri, + ppi->versionstring); + + /* so functions must be a tag_plugin_output_fn */ + auth_fn=(((PLUGIN_OUTPUT_FN*)ppi->functions)->auth); + if(auth_fn) { + result=auth_fn(pwsc,username,pw); + _plugin_unlock(); + return result; + } else { + _plugin_unlock(); + return TRUE; + } + } + ppi = ppi->next; + } + } + + /* should 500 here or something */ + ws_returnerror(pwsc, 500, "Can't find plugin handler"); + _plugin_unlock(); + return FALSE; +} + + /* plugin wrappers for utility functions & stuff * * these functions need to be wrapped so we can maintain a stable diff --git a/src/plugin.h b/src/plugin.h index 4ef84801..5c728bdb 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -31,6 +31,7 @@ extern int plugin_deinit(void); /* Interfaces for web */ extern int plugin_url_candispatch(WS_CONNINFO *pwsc); extern void plugin_url_handle(WS_CONNINFO *pwsc); +extern int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw); #define PLUGIN_E_SUCCESS 0 #define PLUGIN_E_NOLOAD 1 @@ -46,6 +47,7 @@ extern void plugin_url_handle(WS_CONNINFO *pwsc); typedef struct tag_plugin_output_fn { void(*handler)(WS_CONNINFO *pwsc); + int(*auth)(WS_CONNINFO *pwsc, char *username, char *pw); } PLUGIN_OUTPUT_FN; /* version 1 plugin info */