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 @@
+
+