diff --git a/src/configfile.c b/src/configfile.c index 582cc2af..a28b63b9 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -352,10 +352,15 @@ void config_handler(WS_CONNINFO *pwsc) { * \param user username passed in the auth request * \param password password passed in the auth request */ -int config_auth(char *user, char *password) { +int config_auth(char *hostname, char *user, char *password) { char *adminpassword; int res; +#ifdef WIN32 + if((hostname) && (os_islocaladdr(hostname))) + return TRUE; +#endif + if((!password) || ((adminpassword=conf_alloc_string("general","admin_pw",NULL))==NULL)) return FALSE; diff --git a/src/configfile.h b/src/configfile.h index 3b6cc083..f1281ed5 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -25,7 +25,7 @@ #include "daapd.h" #include "webserver.h" -extern int config_auth(char *user, char *password); +extern int config_auth(char *hostname, char *user, char *password); extern void config_handler(WS_CONNINFO *pwsc); extern void config_set_status(WS_CONNINFO *pwsc, int session, char *fmt, ...); extern int config_get_session_count(void); diff --git a/src/dispatch.c b/src/dispatch.c index 6d249c9c..1c7ab629 100644 --- a/src/dispatch.c +++ b/src/dispatch.c @@ -127,7 +127,7 @@ void dispatch_cleanup(DBQUERYINFO *pqi) { * @param password The password passed by iTunes * @returns 1 if auth successful, 0 otherwise */ -int daap_auth(char *username, char *password) { +int daap_auth(char *hostname, char *username, char *password) { char *readpassword; readpassword = conf_alloc_string("general","password",NULL); diff --git a/src/os-win32.c b/src/os-win32.c index cd442e00..5bd511b7 100644 --- a/src/os-win32.c +++ b/src/os-win32.c @@ -203,7 +203,7 @@ int _os_sock_to_fd(SOCKET sock) { return fd + MAXDESC; } -int os_acceptsocket(int fd, char *hostn, int hostnsize) { +int os_acceptsocket(int fd, struct in_addr *hostaddr) { socklen_t len = sizeof(struct sockaddr); struct sockaddr_in netclient; SOCKET retval; @@ -219,12 +219,12 @@ int os_acceptsocket(int fd, char *hostn, int hostnsize) { accept(REALSOCK,(struct sockaddr *)(&netclient), &len)) == SOCKET_ERROR) && (WSAGetLastError() == WSAEINTR)); - if ((retval == INVALID_SOCKET) || (hostn == NULL) || (hostnsize <= 0)) { + if (retval == INVALID_SOCKET) { DPRINTF(E_LOG,L_MISC,"Error accepting...\n"); return _os_sock_to_fd(retval); } - strncpy(hostn,inet_ntoa(netclient.sin_addr),hostnsize); + *hostaddr = netclient.sin_addr; return _os_sock_to_fd(retval); } @@ -618,6 +618,39 @@ char *os_configpath(void) { return os_config_file; } +/** + * Determine if an address is local or not + * + * @param hostaddr the address to test for locality + */ +int os_islocaladdr(char *hostaddr) { + char hostname[256]; + struct hostent *ht; + int index; + + DPRINTF(E_DBG,L_MISC,"Checking if %s is local\n",hostaddr); + + gethostname(hostname, sizeof(hostname)); + ht=gethostbyname(hostname); + + index=0; + while(ht->h_addr_list[index] != NULL) { +/* + if(memcmp(&hostaddr,h_addr_list[index],4) == 0) + return TRUE; +*/ + if(strcmp(inet_ntoa(*(struct in_addr *)ht->h_addr_list[index]),hostaddr) == 0) { + DPRINTF(E_DBG,L_MISC,"Yup!\n"); + return TRUE; + } + index++; + } + + DPRINTF(E_DBG,L_MISC,"Nope!\n"); + return FALSE; +} + + /** * Lock the mutex. This is used for initialization stuff, among * other things (?) diff --git a/src/os-win32.h b/src/os-win32.h index e44770e6..e7f31a17 100644 --- a/src/os-win32.h +++ b/src/os-win32.h @@ -42,10 +42,11 @@ typedef struct { extern int os_register(void); extern int os_unregister(void); extern char *os_configpath(void); +extern int os_islocaladdr(char *hostaddr); /* replacements for socket functions */ extern int os_opensocket(unsigned short port); -extern int os_acceptsocket(int fd, char *hostn, int hostnsize); +extern int os_acceptsocket(int fd, struct in_addr *hostaddr); extern int os_shutdown(int fd, int how); extern int os_waitfdtimed(int fd, struct timeval end); extern int os_close(int fd); diff --git a/src/uici.c b/src/uici.c index e72bcc38..25ef0cc8 100644 --- a/src/uici.c +++ b/src/uici.c @@ -134,7 +134,7 @@ int u_open(u_port_t port) { * into the buffer. * If hostn is NULL or hostnsize <= 0, no hostname is copied. */ -int u_accept(int fd, char *hostn, int hostnsize) { +int u_accept(int fd, char *hostn, strcut in_addr *hostaddr) { socklen_t len = sizeof(struct sockaddr); struct sockaddr_in netclient; int retval; @@ -146,7 +146,7 @@ int u_accept(int fd, char *hostn, int hostnsize) { if ((retval == -1) || (hostn == NULL) || (hostnsize <= 0)) return retval; - strncpy(hostn,inet_ntoa(netclient.sin_addr),hostnsize); + *hostaddr = netclient.sin_addr; return retval; } diff --git a/src/uici.h b/src/uici.h index eff16da7..3937cfe3 100644 --- a/src/uici.h +++ b/src/uici.h @@ -39,5 +39,5 @@ #define UPORT typedef unsigned short u_port_t; int u_open(u_port_t port); -int u_accept(int fd, char *hostn, int hostnsize); +int u_accept(int fd, struct in_addr *hostaddr); int u_connect(u_port_t port, char *hostn); diff --git a/src/webserver.c b/src/webserver.c index 53e448ad..e64dd5a8 100644 --- a/src/webserver.c +++ b/src/webserver.c @@ -64,7 +64,7 @@ typedef struct tag_ws_handler { regex_t regex; void (*req_handler)(WS_CONNINFO*); - int(*auth_handler)(char *, char *); + int(*auth_handler)(char *, char *, char *); int addheaders; struct tag_ws_handler *next; } WS_HANDLER; @@ -107,11 +107,11 @@ char *ws_getarg(ARGLIST *root, char *key); int ws_testarg(ARGLIST *root, char *key, char *value); int ws_findhandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc, void(**preq)(WS_CONNINFO*), - int(**pauth)(char *, char *), + int(**pauth)(char *, char *, char *), int *addheaders); int ws_registerhandler(WSHANDLE ws, char *regex, void(*handler)(WS_CONNINFO*), - int(*auth)(char *, char *), + int(*auth)(char *, char *, char *), int addheaders); int ws_decodepassword(char *header, char **username, char **password); int ws_testrequestheader(WS_CONNINFO *pwsc, char *header, char *value); @@ -402,7 +402,8 @@ void *ws_mainthread(void *arg) { WS_PRIVATE *pwsp = (WS_PRIVATE*)arg; WS_CONNINFO *pwsc; pthread_t tid; - char hostname[MAX_HOSTNAME]; + char hostname[MAX_HOSTNAME+1]; + struct in_addr hostaddr; DPRINTF(E_SPAM,L_WS,"Entering ws_mainthread\n"); @@ -417,7 +418,7 @@ void *ws_mainthread(void *arg) { memset(pwsc,0,sizeof(WS_CONNINFO)); - if((fd=u_accept(pwsp->server_fd,hostname,MAX_HOSTNAME)) == -1) { + if((fd=u_accept(pwsp->server_fd,&hostaddr)) == -1) { DPRINTF(E_LOG,L_WS,"Dispatcher: accept failed: %s\n",strerror(errno)); shutdown(pwsp->server_fd,SHUT_RDWR); r_close(pwsp->server_fd); @@ -428,6 +429,8 @@ void *ws_mainthread(void *arg) { return NULL; } + strncpy(hostname,inet_ntoa(hostaddr),MAX_HOSTNAME); + pwsc->hostname=strdup(hostname); pwsc->fd=fd; pwsc->pwsp = pwsp; @@ -763,7 +766,7 @@ void *ws_dispatcher(void *arg) { time_t now; struct tm now_tm; void (*req_handler)(WS_CONNINFO*); - int(*auth_handler)(char *, char *); + int(*auth_handler)(char *, char *, char *); DPRINTF(E_DBG,L_WS,"Thread %d: Entering ws_dispatcher (Connection from %s)\n", pwsc->threadno, pwsc->hostname); @@ -930,12 +933,12 @@ void *ws_dispatcher(void *arg) { * username and password of NULL, then don't bother * authing. */ - if((auth_handler) && (auth_handler(NULL,NULL)==0)) { + if((auth_handler) && (auth_handler(pwsc->hostname,NULL,NULL)==0)) { /* do the auth thing */ auth=ws_getarg(&pwsc->request_headers,"Authorization"); if(auth) { ws_decodepassword(auth,&username,&password); - if(auth_handler(username,password)) + if(auth_handler(pwsc->hostname,username,password)) can_dispatch=1; ws_addarg(&pwsc->request_vars,"HTTP_USER",username); ws_addarg(&pwsc->request_vars,"HTTP_PASSWD",password); @@ -1321,7 +1324,7 @@ char *ws_urldecode(char *string, int space_as_plus) { */ int ws_registerhandler(WSHANDLE ws, char *regex, void(*handler)(WS_CONNINFO*), - int(*auth)(char *, char *), + int(*auth)(char *, char *, char *), int addheaders) { WS_HANDLER *phandler; WS_PRIVATE *pwsp = (WS_PRIVATE *)ws; @@ -1358,7 +1361,7 @@ int ws_registerhandler(WSHANDLE ws, char *regex, */ int ws_findhandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc, void(**preq)(WS_CONNINFO*), - int(**pauth)(char *, char *), + int(**pauth)(char *, char *, char *), int *addheaders) { WS_HANDLER *phandler=pwsp->handlers.next; diff --git a/src/webserver.h b/src/webserver.h index 41644768..ac9d8e53 100644 --- a/src/webserver.h +++ b/src/webserver.h @@ -70,13 +70,13 @@ typedef struct tag_ws_conninfo { */ #define WS_REQ_HANDLER void (*)(WS_CONNINFO *) -#define WS_AUTH_HANDLER int (*)(char *, char *) +#define WS_AUTH_HANDLER int (*)(char *, char *, char *) extern WSHANDLE ws_start(WSCONFIG *config); extern int ws_stop(WSHANDLE ws); extern int ws_registerhandler(WSHANDLE ws, char *regex, void(*handler)(WS_CONNINFO*), - int(*auth)(char *, char *), + int(*auth)(char *, char *, char *), int addheaders); extern void ws_lock_local_storage(WS_CONNINFO *pwsc); diff --git a/win32/mt-daapd.vcproj b/win32/mt-daapd.vcproj index ce0806a9..193fc710 100644 --- a/win32/mt-daapd.vcproj +++ b/win32/mt-daapd.vcproj @@ -230,6 +230,9 @@ + + @@ -266,6 +269,9 @@ + +