diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0 index 2e82ed1..a34d211 100644 --- a/autom4te.cache/output.0 +++ b/autom4te.cache/output.0 @@ -3370,7 +3370,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu NODOGSPLASH_MAJOR_VERSION=0 -NODOGSPLASH_MINOR_VERSION=9_beta4 +NODOGSPLASH_MINOR_VERSION=9_beta6 NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION diff --git a/configure b/configure index ce3c075..0b1963e 100755 --- a/configure +++ b/configure @@ -3370,7 +3370,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu NODOGSPLASH_MAJOR_VERSION=0 -NODOGSPLASH_MINOR_VERSION=9_beta4 +NODOGSPLASH_MINOR_VERSION=9_beta6 NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION diff --git a/configure.in b/configure.in index c3abb74..4be704b 100644 --- a/configure.in +++ b/configure.in @@ -19,7 +19,7 @@ AC_PROG_CXX AC_SUBST(BUILDROOT) NODOGSPLASH_MAJOR_VERSION=0 -NODOGSPLASH_MINOR_VERSION=9_beta4 +NODOGSPLASH_MINOR_VERSION=9_beta6 NODOGSPLASH_VERSION=$NODOGSPLASH_MAJOR_VERSION.$NODOGSPLASH_MINOR_VERSION AC_SUBST(NODOGSPLASH_MAJOR_VERSION) diff --git a/libhttpd/api.c b/libhttpd/api.c index 53d6e2a..6a024c2 100644 --- a/libhttpd/api.c +++ b/libhttpd/api.c @@ -64,72 +64,72 @@ char *httpdUrlDecode(char *str) { char *httpdRequestMethodName(request *r) { - static char tmpBuf[255]; + static char tmpBuf[255]; - switch(r->request.method) - { - case HTTP_GET: return("GET"); - case HTTP_POST: return("POST"); - default: - snprintf(tmpBuf,255,"Invalid method '%d'", - r->request.method); - return(tmpBuf); - } + switch(r->request.method) + { + case HTTP_GET: return("GET"); + case HTTP_POST: return("POST"); + default: + snprintf(tmpBuf,255,"Invalid method '%d'", + r->request.method); + return(tmpBuf); + } } httpVar *httpdGetVariableByName(request *r, char *name) { - httpVar *curVar; + httpVar *curVar; - curVar = r->variables; - while(curVar) - { - if (strcmp(curVar->name, name) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); } httpVar *httpdGetVariableByPrefix(request *r, char *prefix) { - httpVar *curVar; + httpVar *curVar; - if (prefix == NULL) - return(r->variables); - curVar = r->variables; - while(curVar) - { - if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); } httpVar *httpdGetVariableByPrefixedName(request *r, char *prefix, char *name) { - httpVar *curVar; - int prefixLen; + httpVar *curVar; + int prefixLen; - if (prefix == NULL) - return(r->variables); - curVar = r->variables; - prefixLen = strlen(prefix); - while(curVar) + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + prefixLen = strlen(prefix); + while(curVar) + { + if (strncmp(curVar->name, prefix, prefixLen) == 0 && + strcmp(curVar->name + prefixLen, name) == 0) { - if (strncmp(curVar->name, prefix, prefixLen) == 0 && - strcmp(curVar->name + prefixLen, name) == 0) - { - return(curVar); - } - curVar = curVar->nextVariable; + return(curVar); } - return(NULL); + curVar = curVar->nextVariable; + } + return(NULL); } @@ -137,159 +137,164 @@ httpVar *httpdGetNextVariableByPrefix(curVar, prefix) httpVar *curVar; char *prefix; { - if(curVar) - curVar = curVar->nextVariable; - while(curVar) - { - if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); + if(curVar) + curVar = curVar->nextVariable; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); } int httpdAddVariable(request *r, char *name, char *value) { - httpVar *curVar, *lastVar, *newVar; + httpVar *curVar, *lastVar, *newVar; - while(*name == ' ' || *name == '\t') - name++; - newVar = malloc(sizeof(httpVar)); - bzero(newVar, sizeof(httpVar)); - newVar->name = strdup(name); - newVar->value = strdup(value); - lastVar = NULL; - curVar = r->variables; - while(curVar) + while(*name == ' ' || *name == '\t') + name++; + newVar = malloc(sizeof(httpVar)); + bzero(newVar, sizeof(httpVar)); + newVar->name = strdup(name); + newVar->value = strdup(value); + lastVar = NULL; + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) != 0) { - if (strcmp(curVar->name, name) != 0) - { - lastVar = curVar; - curVar = curVar->nextVariable; - continue; - } - while(curVar) - { - lastVar = curVar; - curVar = curVar->nextValue; - } - lastVar->nextValue = newVar; - return(0); + lastVar = curVar; + curVar = curVar->nextVariable; + continue; } - if (lastVar) - lastVar->nextVariable = newVar; - else - r->variables = newVar; - return(0); + while(curVar) + { + lastVar = curVar; + curVar = curVar->nextValue; + } + lastVar->nextValue = newVar; + return(0); + } + if (lastVar) + lastVar->nextVariable = newVar; + else + r->variables = newVar; + return(0); } +void httpd_storeData(request *r, char *query) { + _httpd_storeData(r,query); +} + + httpd *httpdCreate(host, port) char *host; int port; { - httpd *new; - int sock, - opt; - struct sockaddr_in addr; + httpd *new; + int sock, + opt; + struct sockaddr_in addr; - /* - ** Create the handle and setup it's basic config - */ - new = malloc(sizeof(httpd)); - if (new == NULL) - return(NULL); - bzero(new, sizeof(httpd)); - new->port = port; - if (host == HTTP_ANY_ADDR) - new->host = HTTP_ANY_ADDR; - else - new->host = strdup(host); - new->content = (httpDir*)malloc(sizeof(httpDir)); - bzero(new->content,sizeof(httpDir)); - new->content->name = strdup(""); + /* + ** Create the handle and setup it's basic config + */ + new = malloc(sizeof(httpd)); + if (new == NULL) + return(NULL); + bzero(new, sizeof(httpd)); + new->port = port; + if (host == HTTP_ANY_ADDR) + new->host = HTTP_ANY_ADDR; + else + new->host = strdup(host); + new->content = (httpDir*)malloc(sizeof(httpDir)); + bzero(new->content,sizeof(httpDir)); + new->content->name = strdup(""); - /* - ** Setup the socket - */ + /* + ** Setup the socket + */ #ifdef _WIN32 - { - WORD wVersionRequested; - WSADATA wsaData; - int err; + { + WORD wVersionRequested; + WSADATA wsaData; + int err; - wVersionRequested = MAKEWORD( 2, 2 ); + wVersionRequested = MAKEWORD( 2, 2 ); - err = WSAStartup( wVersionRequested, &wsaData ); + err = WSAStartup( wVersionRequested, &wsaData ); - /* Found a usable winsock dll? */ - if( err != 0 ) - return NULL; + /* Found a usable winsock dll? */ + if( err != 0 ) + return NULL; - /* - ** Confirm that the WinSock DLL supports 2.2. - ** Note that if the DLL supports versions greater - ** than 2.2 in addition to 2.2, it will still return - ** 2.2 in wVersion since that is the version we - ** requested. - */ + /* + ** Confirm that the WinSock DLL supports 2.2. + ** Note that if the DLL supports versions greater + ** than 2.2 in addition to 2.2, it will still return + ** 2.2 in wVersion since that is the version we + ** requested. + */ - if( LOBYTE( wsaData.wVersion ) != 2 || - HIBYTE( wsaData.wVersion ) != 2 ) { + if( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) { - /* - ** Tell the user that we could not find a usable - ** WinSock DLL. - */ - WSACleanup( ); - return NULL; - } + /* + ** Tell the user that we could not find a usable + ** WinSock DLL. + */ + WSACleanup( ); + return NULL; + } - /* The WinSock DLL is acceptable. Proceed. */ - } + /* The WinSock DLL is acceptable. Proceed. */ + } #endif - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - { - free(new); - return(NULL); - } + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + free(new); + return(NULL); + } # ifdef SO_REUSEADDR - opt = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int)); + opt = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int)); # endif - new->serverSock = sock; - bzero(&addr, sizeof(addr)); - addr.sin_family = AF_INET; - if (new->host == HTTP_ANY_ADDR) - { - addr.sin_addr.s_addr = htonl(INADDR_ANY); - } - else - { - addr.sin_addr.s_addr = inet_addr(new->host); - } - addr.sin_port = htons((u_short)new->port); - if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) - { - close(sock); - free(new); - return(NULL); - } - listen(sock, 128); - new->startTime = time(NULL); - return(new); + new->serverSock = sock; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + if (new->host == HTTP_ANY_ADDR) + { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + addr.sin_addr.s_addr = inet_addr(new->host); + } + addr.sin_port = htons((u_short)new->port); + if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) + { + close(sock); + free(new); + return(NULL); + } + listen(sock, 128); + new->startTime = time(NULL); + return(new); } void httpdDestroy(server) httpd *server; { - if (server == NULL) - return; - if (server->host) - free(server->host); - free(server); + if (server == NULL) + return; + if (server->host) + free(server->host); + free(server); } @@ -298,73 +303,73 @@ request *httpdGetConnection(server, timeout) httpd *server; struct timeval *timeout; { - int result; - fd_set fds; - struct sockaddr_in addr; - size_t addrLen; - char *ipaddr; - request *r; + int result; + fd_set fds; + struct sockaddr_in addr; + size_t addrLen; + char *ipaddr; + request *r; - FD_ZERO(&fds); - FD_SET(server->serverSock, &fds); - result = 0; - while(result == 0) + FD_ZERO(&fds); + FD_SET(server->serverSock, &fds); + result = 0; + while(result == 0) + { + result = select(server->serverSock + 1, &fds, 0, 0, timeout); + if (result < 0) { - result = select(server->serverSock + 1, &fds, 0, 0, timeout); - if (result < 0) - { - server->lastError = -1; - return(NULL); - } - if (timeout != 0 && result == 0) - { - return(NULL); - server->lastError = 0; - } - if (result > 0) - { - break; - } + server->lastError = -1; + return(NULL); } - /* Allocate request struct */ - r = (request *)malloc(sizeof(request)); - if (r == NULL) { - server->lastError = -3; - return(NULL); + if (timeout != 0 && result == 0) + { + return(NULL); + server->lastError = 0; } - memset((void *)r, 0, sizeof(request)); - /* Get on with it */ - bzero(&addr, sizeof(addr)); - addrLen = sizeof(addr); - r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, - &addrLen); - ipaddr = inet_ntoa(addr.sin_addr); - if (ipaddr) - strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); - else - *r->clientAddr = 0; - r->readBufRemain = 0; - r->readBufPtr = NULL; + if (result > 0) + { + break; + } + } + /* Allocate request struct */ + r = (request *)malloc(sizeof(request)); + if (r == NULL) { + server->lastError = -3; + return(NULL); + } + memset((void *)r, 0, sizeof(request)); + /* Get on with it */ + bzero(&addr, sizeof(addr)); + addrLen = sizeof(addr); + r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, + &addrLen); + ipaddr = inet_ntoa(addr.sin_addr); + if (ipaddr) + strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); + else + *r->clientAddr = 0; + r->readBufRemain = 0; + r->readBufPtr = NULL; - /* - ** Check the default ACL - */ - if (server->defaultAcl) + /* + ** Check the default ACL + */ + if (server->defaultAcl) + { + if (httpdCheckAcl(server, r, server->defaultAcl) + == HTTP_ACL_DENY) { - if (httpdCheckAcl(server, r, server->defaultAcl) - == HTTP_ACL_DENY) - { - httpdEndRequest(r); - server->lastError = 2; - return(NULL); - } + httpdEndRequest(r); + server->lastError = 2; + return(NULL); } - return(r); + } + return(r); } -/** N.B.: Functionality removed when not needed for nodogsplash. +/** N.B.: Functionality removed when not desired for nodogsplash. * See #if 0 / #endif deletions below. --P. Kube */ int httpdReadRequest(httpd *server, request *r) @@ -580,44 +585,44 @@ int httpdReadRequest(httpd *server, request *r) void httpdEndRequest(request *r) { - _httpd_freeVariables(r->variables); - shutdown(r->clientSock,2); - close(r->clientSock); - free(r); + _httpd_freeVariables(r->variables); + shutdown(r->clientSock,2); + close(r->clientSock); + free(r); } void httpdFreeVariables(request *r) { - _httpd_freeVariables(r->variables); + _httpd_freeVariables(r->variables); } void httpdDumpVariables(request *r) { - httpVar *curVar, - *curVal; + httpVar *curVar, + *curVal; - curVar = r->variables; - while(curVar) + curVar = r->variables; + while(curVar) + { + printf("Variable '%s'\n", curVar->name); + curVal = curVar; + while(curVal) { - printf("Variable '%s'\n", curVar->name); - curVal = curVar; - while(curVal) - { - printf("\t= '%s'\n",curVal->value); - curVal = curVal->nextValue; - } - curVar = curVar->nextVariable; + printf("\t= '%s'\n",curVal->value); + curVal = curVal->nextValue; } + curVar = curVar->nextVariable; + } } void httpdSetFileBase(server, path) httpd *server; char *path; { - strncpy(server->fileBasePath, path, HTTP_MAX_URL); + strncpy(server->fileBasePath, path, HTTP_MAX_URL); } @@ -629,34 +634,34 @@ int httpdAddFileContent(server, dir, name, indexFlag, preload, path) int indexFlag; char *path; { - httpDir *dirPtr; - httpContent *newEntry; + httpDir *dirPtr; + httpContent *newEntry; - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_FILE; - newEntry->indexFlag = indexFlag; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - if (*path == '/') - { - /* Absolute path */ - newEntry->path = strdup(path); - } - else - { - /* Path relative to base path */ - newEntry->path = malloc(strlen(server->fileBasePath) + - strlen(path) + 2); - snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", - server->fileBasePath, path); - } - return(0); + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_FILE; + newEntry->indexFlag = indexFlag; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); } @@ -667,34 +672,34 @@ int httpdAddWildcardContent(server, dir, preload, path) int (*preload)(); char *path; { - httpDir *dirPtr; - httpContent *newEntry; + httpDir *dirPtr; + httpContent *newEntry; - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = NULL; - newEntry->type = HTTP_WILDCARD; - newEntry->indexFlag = HTTP_FALSE; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - if (*path == '/') - { - /* Absolute path */ - newEntry->path = strdup(path); - } - else - { - /* Path relative to base path */ - newEntry->path = malloc(strlen(server->fileBasePath) + - strlen(path) + 2); - snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", - server->fileBasePath, path); - } - return(0); + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); } @@ -704,16 +709,16 @@ int httpdAddC404Content(server, function) httpd *server; void (*function)(); { - if (!server->handle404) { - server->handle404 = (http404*)malloc(sizeof(http404)); - } + if (!server->handle404) { + server->handle404 = (http404*)malloc(sizeof(http404)); + } - if (!server->handle404) { - return(-1); - } + if (!server->handle404) { + return(-1); + } - server->handle404->function = function; - return(0); + server->handle404->function = function; + return(0); } int httpdAddCContent(server, dir, name, indexFlag, preload, function) @@ -723,22 +728,22 @@ int httpdAddCContent(server, dir, name, indexFlag, preload, function) int (*preload)(); void (*function)(); { - httpDir *dirPtr; - httpContent *newEntry; + httpDir *dirPtr; + httpContent *newEntry; - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_C_FUNCT; - newEntry->indexFlag = indexFlag; - newEntry->function = function; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_C_FUNCT; + newEntry->indexFlag = indexFlag; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); } @@ -748,22 +753,22 @@ int httpdAddCWildcardContent(server, dir, preload, function) int (*preload)(); void (*function)(); { - httpDir *dirPtr; - httpContent *newEntry; + httpDir *dirPtr; + httpContent *newEntry; - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = NULL; - newEntry->type = HTTP_C_WILDCARD; - newEntry->indexFlag = HTTP_FALSE; - newEntry->function = function; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_C_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); } int httpdAddStaticContent(server, dir, name, indexFlag, preload, data) @@ -773,109 +778,103 @@ int httpdAddStaticContent(server, dir, name, indexFlag, preload, data) int (*preload)(); char *data; { - httpDir *dirPtr; - httpContent *newEntry; + httpDir *dirPtr; + httpContent *newEntry; - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_STATIC; - newEntry->indexFlag = indexFlag; - newEntry->data = data; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_STATIC; + newEntry->indexFlag = indexFlag; + newEntry->data = data; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); } -void httpdSendHeaders(request *r) -{ - _httpd_sendHeaders(r, 0, 0); +void httpdSendHeaders(request *r) { + _httpd_sendHeaders(r, 0, 0); } -void httpdSetResponse(request *r, char *msg) -{ - strncpy(r->response.response, msg, HTTP_MAX_URL); +void httpdSetResponse(request *r, char *msg) { + strncpy(r->response.response, msg, HTTP_MAX_URL); } -void httpdSetContentType(request *r, char *type) -{ - strcpy(r->response.contentType, type); +void httpdSetContentType(request *r, char *type) { + strcpy(r->response.contentType, type); } -void httpdAddHeader(request *r, char *msg) -{ - strcat(r->response.headers,msg); - if (msg[strlen(msg) - 1] != '\n') - strcat(r->response.headers,"\n"); +void httpdAddHeader(request *r, char *msg) { + strcat(r->response.headers,msg); + if (msg[strlen(msg) - 1] != '\n') + strcat(r->response.headers,"\n"); } -void httpdSetCookie(request *r, char *name, char *value) -{ - char buf[HTTP_MAX_URL]; +void httpdSetCookie(request *r, char *name, char *value) { + char buf[HTTP_MAX_URL]; - snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value); - httpdAddHeader(r, buf); + snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value); + httpdAddHeader(r, buf); } -void httpdOutput(request *r, char *msg) -{ - char buf[HTTP_MAX_LEN], - varName[80], - *src, - *dest; - int count; +void httpdOutput(request *r, char *msg) { + char buf[HTTP_MAX_LEN], + varName[80], + *src, + *dest; + int count; - src = msg; - dest = buf; - count = 0; - while(*src && count < HTTP_MAX_LEN) + src = msg; + dest = buf; + count = 0; + while(*src && count < HTTP_MAX_LEN) + { + if (*src == '$') { - if (*src == '$') - { - char *cp, - *tmp; - int count2; - httpVar *curVar; + char *cp, + *tmp; + int count2; + httpVar *curVar; - tmp = src + 1; - cp = varName; - count2 = 0; - while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80) - { - *cp++ = *tmp++; - count2++; - } - *cp = 0; - curVar = httpdGetVariableByName(r,varName); - if (curVar) - { - strcpy(dest, curVar->value); - dest = dest + strlen(dest); - count += strlen(dest); - } - else - { - *dest++ = '$'; - strcpy(dest, varName); - dest += strlen(varName); - count += 1 + strlen(varName); - } - src = src + strlen(varName) + 1; - continue; - } - *dest++ = *src++; - count++; - } - *dest = 0; - r->response.responseLength += strlen(buf); - if (r->response.headersSent == 0) - httpdSendHeaders(r); - _httpd_net_write( r->clientSock, buf, strlen(buf)); + tmp = src + 1; + cp = varName; + count2 = 0; + while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80) + { + *cp++ = *tmp++; + count2++; + } + *cp = 0; + curVar = httpdGetVariableByName(r,varName); + if (curVar) + { + strcpy(dest, curVar->value); + dest = dest + strlen(dest); + count += strlen(dest); + } + else + { + *dest++ = '$'; + strcpy(dest, varName); + dest += strlen(varName); + count += 1 + strlen(varName); + } + src = src + strlen(varName) + 1; + continue; + } + *dest++ = *src++; + count++; + } + *dest = 0; + r->response.responseLength += strlen(buf); + if (r->response.headersSent == 0) + httpdSendHeaders(r); + _httpd_net_write( r->clientSock, buf, strlen(buf)); } diff --git a/libhttpd/httpd.h b/libhttpd/httpd.h index d8b77bf..daa421c 100644 --- a/libhttpd/httpd.h +++ b/libhttpd/httpd.h @@ -192,6 +192,8 @@ int httpdAddStaticContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); int httpdAddWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),char*)); int httpdAddCWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),void(*)())); int httpdAddVariable __ANSI_PROTO((request*, char*, char*)); +void httpd_storeData __ANSI_PROTO((request*, char*)); + request *httpdGetConnection __ANSI_PROTO((httpd*, struct timeval*)); int httpdReadRequest __ANSI_PROTO((httpd*, request*)); int httpdCheckAcl __ANSI_PROTO((httpd*, request *, httpAcl*)); diff --git a/libhttpd/protocol.c b/libhttpd/protocol.c index 43807e2..f1a139f 100644 --- a/libhttpd/protocol.c +++ b/libhttpd/protocol.c @@ -673,10 +673,9 @@ static unsigned char isAcceptable[96] = /* Bit 0 xalpha -- see HTFile.h ** Bit 1 xpalpha -- as xalpha but with plus. ** Bit 2 ... path -- as xpalpha but with / -** N.B.: changed to disallow space, / */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - { 0,0,0,0,0,0,0,0,0,0,7,0,0,7,7,0, /* 2x !"#$%&'()*+,-./ */ + { 7,0,0,0,0,0,0,0,0,0,7,0,0,7,7,0, /* 2x !"#$%&'()*+,-./ */ 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ @@ -688,7 +687,6 @@ static unsigned char isAcceptable[96] = static char *hex = "0123456789ABCDEF"; -/*TODO: fix so spaces are encoded as + */ char *_httpd_escape(str) char *str; { @@ -697,9 +695,11 @@ char *_httpd_escape(str) char * q; char * result; int unacceptable = 0; - for(p=str; *p; p++) - if (!ACCEPTABLE((unsigned char)*p)) + for(p=str; *p; p++) { + if (!ACCEPTABLE((unsigned char)*p)) { unacceptable +=2; + } + } result = (char *) malloc(p-str + unacceptable + 1); bzero(result,(p-str + unacceptable + 1)); @@ -710,18 +710,20 @@ char *_httpd_escape(str) for(q=result, p=str; *p; p++) { unsigned char a = *p; if (!ACCEPTABLE(a)) { - *q++ = '%'; /* Means hex commming */ + *q++ = '%'; /* Means hex coming */ *q++ = hex[a >> 4]; *q++ = hex[a & 15]; - } - else *q++ = *p; + } else if (a == ' ') { + *q++ = '+'; /* space becomes + */ + } else { + *q++ = *p; + } } *q++ = 0; /* Terminate */ return result; } - void _httpd_sanitiseUrl(url) char *url; { diff --git a/nodogsplash.conf b/nodogsplash.conf index 99b79f7..f5bc25f 100644 --- a/nodogsplash.conf +++ b/nodogsplash.conf @@ -50,7 +50,7 @@ FirewallRuleSet authenticated-users { } # end FirewallRuleSet authenticated-users -# FirewallRuleSet: to-router +# FirewallRuleSet: users-to-router # # Control access to the router itself from the GatewayInterface. # These rules are inserted at the beginning of the @@ -155,32 +155,16 @@ FirewallRuleSet users-to-router { # ClientForceTimeout 360 -# Parameter: AuthenticatorAddress -# Default: none -# -# If you are using another server to do authentication -# (for example password authentication) specify its IP address here. - -# AuthenticatorAddress 192.168.1.1 - -# Parameter: AuthenticatorPort -# Default: 80 -# -# If you are using another server to do authentication -# (for example password authentication) specify its port here. - -# AuthenticatorPort 80 - # Parameter: AuthenticateImmediately # Default: no # # Set to yes (or true or 1), to immediately authenticate users # who make a http port 80 request on the GatewayInterface (i.e. -# do not serve a splash page or any authentication server). +# do not serve a splash page or redirect to any remote authenticator; +# just redirect to the user's request, or to RedirectURL if set). # AuthenticateImmediately no - # Parameter: BlockedMACList # Default: none # diff --git a/src/conf.c b/src/conf.c index 4275643..35ce61f 100644 --- a/src/conf.c +++ b/src/conf.c @@ -71,8 +71,9 @@ typedef enum { oGatewayInterface, oGatewayAddress, oGatewayPort, - oAuthenticatorAddress, - oAuthenticatorPort, + oRemoteAuthenticatorAddress, + oRemoteAuthenticatorPort, + oRemoteAuthenticatorPath, oHTTPDMaxConn, oWebRoot, oSplashPage, @@ -111,8 +112,9 @@ static const struct { { "gatewayinterface", oGatewayInterface }, { "gatewayaddress", oGatewayAddress }, { "gatewayport", oGatewayPort }, - { "authenticatoraddress", oAuthenticatorAddress }, - { "authenticatorport", oAuthenticatorPort }, + { "remoteauthenticatoraddress", oRemoteAuthenticatorAddress }, + { "remoteauthenticatorport", oRemoteAuthenticatorPort }, + { "remoteauthenticatorpath", oRemoteAuthenticatorPath }, { "webroot", oWebRoot }, { "splashpage", oSplashPage }, { "imagesdir", oImagesDir }, @@ -159,8 +161,8 @@ config_init(void) { config.gw_interface = NULL; config.gw_address = NULL; config.gw_port = DEFAULT_GATEWAYPORT; - config.authenticator_address = NULL; - config.authenticator_port = DEFAULT_AUTHENTICATORPORT; + config.remote_auth_address = NULL; + config.remote_auth_port = DEFAULT_REMOTE_AUTH_PORT; config.webroot = DEFAULT_WEBROOT; config.splashpage = DEFAULT_SPLASHPAGE; config.imagesdir = DEFAULT_IMAGESDIR; @@ -571,11 +573,14 @@ config_read(char *filename) { case oGatewayPort: sscanf(p1, "%d", &config.gw_port); break; - case oAuthenticatorAddress: - config.authenticator_address = safe_strdup(p1); + case oRemoteAuthenticatorAddress: + config.remote_auth_address = safe_strdup(p1); break; - case oAuthenticatorPort: - sscanf(p1, "%d", &config.authenticator_port); + case oRemoteAuthenticatorPort: + sscanf(p1, "%d", &config.remote_auth_port); + break; + case oRemoteAuthenticatorPath: + config.remote_auth_path = safe_strdup(p1); break; case oFirewallRuleSet: parse_firewall_ruleset(p1, fd, filename, &linenum); diff --git a/src/conf.h b/src/conf.h index 4e3bd8d..163544f 100644 --- a/src/conf.h +++ b/src/conf.h @@ -46,7 +46,7 @@ #define DEFAULT_MAXCLIENTS 20 #define DEFAULT_GATEWAYNAME "NoDogSplash" #define DEFAULT_GATEWAYPORT 2050 -#define DEFAULT_AUTHENTICATORPORT 80 +#define DEFAULT_REMOTE_AUTH_PORT 80 #define DEFAULT_CHECKINTERVAL 60 #define DEFAULT_CLIENTTIMEOUT 10 #define DEFAULT_CLIENTFORCEOUT 360 @@ -112,8 +112,9 @@ typedef struct { char *gw_interface; /**< @brief Interface we will accept connections on */ char *gw_address; /**< @brief Internal IP address for our web server */ int gw_port; /**< @brief Port the webserver will run on */ - char *authenticator_address; /**< @brief IP address for custom web server */ - int authenticator_port; /**< @brief Port the custom webserver will run on */ + char *remote_auth_address; /**< @brief IP address for remote auth */ + int remote_auth_port; /**< @brief Port the remote auth listens on */ + char *remote_auth_path; /**< @brief Path for remote auth cgi */ char *webroot; /**< @brief Directory containing splash pages, etc. */ char *splashpage; /**< @brief Name of main splash page */ char *imagesdir; /**< @brief Subdir of webroot containing .png .gif files etc */ diff --git a/src/http.c b/src/http.c index a9302b6..b4855be 100644 --- a/src/http.c +++ b/src/http.c @@ -176,7 +176,6 @@ http_nodogsplash_footer(request *r) { /** The 404 handler is one way a client can first hit nodogsplash. - * Adds the client to the client list and serves the splash page. */ void http_nodogsplash_callback_404(httpd *webserver, request *r) { @@ -189,7 +188,6 @@ http_nodogsplash_callback_404(httpd *webserver, request *r) { /** The index handler is one way a client can first hit nodogsplash. - * Adds the client to the client list and serves the splash page. */ void http_nodogsplash_callback_index(httpd *webserver, request *r) { @@ -200,32 +198,40 @@ http_nodogsplash_callback_index(httpd *webserver, request *r) { http_nodogsplash_first_contact(r); } -/** The index handler is one way a client can first hit nodogsplash. - * Adds the client to the client list and serves the splash page. +/** Respond to attempted access from a preauthenticated client. + * Add the client to the client list and serves the splash page. */ void http_nodogsplash_first_contact(request *r) { t_client *client; - char *authtarget; + t_auth_target *authtarget; s_config *config; config = config_get_config(); client = http_nodogsplash_add_client(r); - + /* http_nodogsplash_add_client() should log and return null on error */ if(!client) return; + authtarget = + http_nodogsplash_make_authtarget(client->token, + r->request.host, + r->request.path); + if(config->authenticate_immediately) { - authtarget = http_nodogsplash_encode_authtarget(r,client->token); - http_nodogsplash_redirect(r,authtarget); - free(authtarget); + http_nodogsplash_callback_action(r,authtarget,AUTH_MAKE_AUTHENTICATED); } else { - http_nodogsplash_serve_splash(r,client->token); + /* TODO: If RemoteAuthenticator is set, + * use http_nodogsplash_encode_remote_auth() to construct a URL + * and redirect to it instead of serving splash page + */ + http_nodogsplash_serve_splash(r,authtarget); } + + http_nodogsplash_free_authtarget(authtarget); + } - - void _report_warning(request *r, char *msg) { debug(LOG_WARNING, msg); @@ -234,33 +240,39 @@ _report_warning(request *r, char *msg) { http_nodogsplash_footer(r); } -/** The multipurpose handler */ +/** The multipurpose authentication action handler + */ void -http_nodogsplash_callback_action(request *r, t_authaction action) { +http_nodogsplash_callback_action(request *r, + t_auth_target *authtarget, + t_authaction action) { t_client *client; char *mac; char *ip; - char *redir = NULL; char *clienttoken = NULL; - char *requesttoken = NULL; + char *requesttoken = authtarget->token; + char *redir = authtarget->redir; s_config *config; config = config_get_config(); - /* Get components of path in request */ - http_nodogsplash_decode_authtarget(r, &requesttoken, &redir); - ip = r->clientAddr; + if(!requesttoken) { + debug(LOG_WARNING, "No token in request from ip %s", ip); + return; + } + if(!redir) { + debug(LOG_WARNING, "No redirect in request from ip %s", ip); + return; + } + if (!(mac = arp_get(ip))) { /* We could not get their MAC address */ - debug(LOG_WARNING, "Failed to retrieve MAC address for ip %s", ip); http_nodogsplash_header(r, "Nodogsplash Error"); httpdOutput(r, "Failed to retrieve your MAC address."); http_nodogsplash_footer(r); - free(requesttoken); - free(redir); return; } @@ -277,17 +289,10 @@ http_nodogsplash_callback_action(request *r, t_authaction action) { httpdOutput(r, "You are not on the client list."); http_nodogsplash_footer(r); free(mac); - free(requesttoken); - free(redir); return; } /* We have a client */ - /* If there is a redir in the config, use it instead of redir in this request */ - if(config->redirectURL) { - free(redir); - redir = safe_strdup(config->redirectURL); - } /* Do we have a client token? */ if(!clienttoken) { @@ -296,8 +301,6 @@ http_nodogsplash_callback_action(request *r, t_authaction action) { httpdOutput(r, "No token available."); http_nodogsplash_footer(r); free(mac); - free(requesttoken); - free(redir); return; } @@ -315,7 +318,7 @@ http_nodogsplash_callback_action(request *r, t_authaction action) { case AUTH_MAKE_DEAUTHENTICATED: auth_client_action(ip,mac,action); http_nodogsplash_header(r, "Nodogsplash Deny"); - httpdOutput(r, "OK, see you later!"); + httpdOutput(r, "Authentication revoked."); http_nodogsplash_footer(r); break; default: @@ -331,8 +334,6 @@ http_nodogsplash_callback_action(request *r, t_authaction action) { http_nodogsplash_footer(r); } free(mac); - free(redir); - free(requesttoken); free(clienttoken); } @@ -340,17 +341,23 @@ http_nodogsplash_callback_action(request *r, t_authaction action) { /** The auth handler registers the client as authenticated, and redirects their web request */ void http_nodogsplash_callback_auth(httpd *webserver, request *r) { + t_auth_target *authtarget; - http_nodogsplash_callback_action ( r, AUTH_MAKE_AUTHENTICATED ); - + /* Get info we need from request */ + authtarget = http_nodogsplash_decode_authtarget(r); + http_nodogsplash_callback_action (r,authtarget,AUTH_MAKE_AUTHENTICATED ); + http_nodogsplash_free_authtarget(authtarget); } /** The deny handler removes the client from the client list */ void http_nodogsplash_callback_deny(httpd *webserver, request *r) { + t_auth_target *authtarget; - http_nodogsplash_callback_action ( r, AUTH_MAKE_DEAUTHENTICATED ); - + /* Get info we need from request */ + authtarget = http_nodogsplash_decode_authtarget(r); + http_nodogsplash_callback_action (r,authtarget,AUTH_MAKE_DEAUTHENTICATED ); + http_nodogsplash_free_authtarget(authtarget); } @@ -375,7 +382,6 @@ http_nodogsplash_add_client(request *r) { debug(LOG_WARNING, "Failed to retrieve MAC address for ip %s", r->clientAddr); } - LOCK_CLIENT_LIST(); if ((client = client_list_find(r->clientAddr, mac)) == NULL) { @@ -394,19 +400,23 @@ http_nodogsplash_add_client(request *r) { } /** - * */ -void -http_nodogsplash_decode_authtarget(request *r, char **token, char **redir) { +t_auth_target * +http_nodogsplash_decode_authtarget(request *r) { char *enccopy, *p1, *p2; + httpVar *var; + t_auth_target *authtarget; + /* Make a copy of encoded path because we will modify it */ enccopy = safe_strdup(r->request.path); /* enccopy should have the form: //, - * where has had its effect already so we ignore it here, - * and where has been httpdUrlEncoded. + * where has had its effect already in determining which + * callback is procesing the request, so we ignore it here, + * and where is a string encoding variables and values in the + * usual way. * (See http_nodogsplash_encode_authtarget() for details.) - * So, here we find and httpdUrlDecode it, - * to see that has the form: / + * So, here we find and store variable/value pairs in the request, + * to find values of token and redir. */ p1 = strchr(enccopy,'/'); /* initial slash */ if(!p1) { _report_warning(r,"Malformed action request: first"); free(enccopy); return; } @@ -414,61 +424,142 @@ http_nodogsplash_decode_authtarget(request *r, char **token, char **redir) { p1 = strchr(p1,'/'); /* second slash */ if(!p1) { _report_warning(r,"Malformed action request: second"); free(enccopy); return; } p1++; - /* httpdUrlDecode the rest. This recovers slashes, among other things. */ - p1 = httpdUrlDecode(p1); /* Note: this decodes in-place */ - /* now look for / */ - p2 = strchr(p1,'/'); /* third slash */ - if(!p2) { _report_warning(r,"Malformed action request: third"); free(enccopy); return; } - *p2 = '\0'; - /* p1 now pointing at terminated token; allocate a copy */ - *token = safe_strdup(p1); - p2++; - /* p2 now pointing at decoded redirect; allocate a copy */ - safe_asprintf(redir,"http://%s",p2); + httpd_storeData(r,p1); + + authtarget = http_nodogsplash_make_authtarget_from_request(r); free(enccopy); + return authtarget; } /** - * Return a pointer to a string encoding a URL which when served will authenticate - * a client. - * Caller must free. + * Allocate and return a pointer to a t_auth_target struct encoding information + * needed to eventually authenticate a client. + * The struct should be freed by http_nodogsplash_free_authtarget(). */ -char * -http_nodogsplash_encode_authtarget(request *r, char *token) { - char *encodedthp, *tokenhostpath, *authtarget; - s_config *config; +t_auth_target* +http_nodogsplash_make_authtarget(char* token, char* redirhost, char* redirpath) { + + t_auth_target* authtarget; + s_config *config; config = config_get_config(); - - safe_asprintf(&tokenhostpath,"%s/%s%s", token, r->request.host, r->request.path); - /* We httpdUrlEncode() the concatenation of token, host, path. - * (host and path are ultimately for the redirect after authentication.) - * This requires a modified version of libhttpd's httpdUrlEncode() - * which encodes slashes (as well as the usual things). - * This is because we must have an - * authtarget that looks like a top-level directory and a file in it. - * (Similarly for denytarget.) - * Slashes will be recovered when we httpdUrlDecode() in - * http_nodogsplash_callback_action(). - */ - encodedthp = httpdUrlEncode(tokenhostpath); /* malloc's */ - safe_asprintf(&authtarget, "http://%s:%d/%s/%s", - config->gw_address, config->gw_port, config->authdir, encodedthp); - free(tokenhostpath); - free(encodedthp); + + authtarget = safe_malloc(sizeof(t_auth_target)); + memset(authtarget, 0, sizeof(t_auth_target)); + authtarget->ip = safe_strdup(config->gw_address); + authtarget->port = config->gw_port; + authtarget->authdir = safe_strdup(config->authdir); + authtarget->denydir = safe_strdup(config->denydir); + authtarget->token = safe_strdup(token); + if(config->redirectURL) { + debug(LOG_DEBUG,"Client requested http://%s%s, substituting %s", + redirhost,redirpath,config->redirectURL); + authtarget->redir = safe_strdup(config->redirectURL); + } else { + safe_asprintf(&(authtarget->redir),"http://%s%s",redirhost,redirpath); + } + + return authtarget; +} + +/** + * Allocate and return a pointer to a t_auth_target struct encoding information + * needed to eventually authenticate a client. + * The struct should be freed by http_nodogsplash_free_authtarget(). + */ +t_auth_target* +http_nodogsplash_make_authtarget_from_request(request *r) { + + t_auth_target* authtarget; + httpVar* var; + + authtarget = safe_malloc(sizeof(t_auth_target)); + memset(authtarget, 0, sizeof(t_auth_target)); + + var = httpdGetVariableByName(r,"tok"); + authtarget->token = safe_strdup(var->value); + var = httpdGetVariableByName(r,"redir"); + authtarget->redir = safe_strdup(var->value); + return authtarget; } -/* Given a client request, serve the splash page from its file. */ + void -http_nodogsplash_serve_splash(request *r, char *token) { +http_nodogsplash_free_authtarget(t_auth_target* authtarget) { + + if(authtarget->ip) free(authtarget->ip); + if(authtarget->authdir) free(authtarget->authdir); + if(authtarget->denydir) free(authtarget->denydir); + if(authtarget->token) free(authtarget->token); + if(authtarget->redir) free(authtarget->redir); + free(authtarget); + +} + +/** + * Return a pointer to a URL string + * which when served will authenticate a client. + * Caller must free. + */ +char * +http_nodogsplash_encode_authtarget(t_auth_target *authtarget) { + char *encodedredir, *encodedtoken, *encodedauthtarget; + + /* URL encode the redirect URL and the token */ + encodedredir = httpdUrlEncode(authtarget->redir); /* malloc's */ + encodedtoken = httpdUrlEncode(authtarget->token); /* malloc's */ + + safe_asprintf(&encodedauthtarget, "http://%s:%d/%s/tok=%s&redir=%s", + authtarget->ip, + authtarget->port, + authtarget->authdir, + encodedtoken, + encodedredir); + + free(encodedredir); + free(encodedtoken); + return encodedauthtarget; +} + +/** + * Return a pointer to a URL string for a remote authenticator. + * Information passed to the remote cgi variable-value arguments. + * Caller must free. + */ +char * +http_nodogsplash_encode_remote_auth(t_auth_target *authtarget) { + char *encodedredir, *url; + s_config *config; + + config = config_get_config(); + encodedredir = httpdUrlEncode(authtarget->redir); /* malloc's */ + safe_asprintf(&url,"http://%s:d/%s?ip=%s&pt=%d&auth=%s&deny=%s&tok=%s&redir=%s", + config->remote_auth_address, + config->remote_auth_port, + config->remote_auth_path, + authtarget->ip, + authtarget->port, + authtarget->authdir, + authtarget->denydir, + authtarget->token, + encodedredir); + free(encodedredir); + return url; +} + + +/* Given a client request, pipe the splash page from the splash page file. */ +void +http_nodogsplash_serve_splash(request *r, t_auth_target *authtarget) { char *redirectURL; char line [MAX_BUF]; - char *splashfilename, *authtarget, *denytarget, *imagesdir; + char *splashfilename, *authtargetstr, *imagesdir; char *encodedthp, *tokenhostpath; FILE *fd; + s_config *config; @@ -477,17 +568,11 @@ http_nodogsplash_serve_splash(request *r, char *token) { httpdAddVariable(r,"gatewayname",config->gw_name); - /* Get auth and deny targets. */ - authtarget = http_nodogsplash_encode_authtarget(r,token); - httpdAddVariable(r,"authtarget",authtarget); - free(authtarget); + /* Get auth target as a string */ + authtargetstr = http_nodogsplash_encode_authtarget(authtarget); + httpdAddVariable(r,"authtarget",authtargetstr); + free(authtargetstr); - /* - denytarget = http_nodogsplash_encode_deyntarget(r,token); - httpdAddVariable(r,"denytarget",denytarget); - free(denytarget); - */ - safe_asprintf(&imagesdir, "/%s", config->imagesdir); httpdAddVariable(r,"imagesdir",imagesdir); free(imagesdir); diff --git a/src/http.h b/src/http.h index 1e83bef..4ce04fb 100644 --- a/src/http.h +++ b/src/http.h @@ -27,9 +27,22 @@ #ifndef _HTTP_H_ #define _HTTP_H_ +#include "auth.h" #include "httpd.h" #include "client_list.h" +/** + * Define parts of an authentication target. + */ +typedef struct _auth_target_t { + char *ip; /**< @brief IP of auth server */ + int port; /**< @brief Port of auth server */ + char *authdir; /**< @brief Auth dir */ + char *denydir; /**< @brief Deny dir */ + char *token; /**< @brief Client token */ + char *redir; /**< @brief Client redirect target */ +} t_auth_target; + /**@brief Callback for libhttpd, serves nodogsplash splash page */ void http_nodogsplash_callback_404(httpd *webserver, request *r); /**@brief Callback for libhttpd, serves nodogsplash splash page */ @@ -38,18 +51,26 @@ void http_nodogsplash_callback_index(httpd *webserver, request *r); void http_nodogsplash_callback_auth(httpd *webserver, request *r); /**@brief Callback for libhttpd, denies a client for nodogsplash */ void http_nodogsplash_callback_deny(httpd *webserver, request *r); +/**@brief The multipurpose authentication action handler */ +void http_nodogsplash_callback_action(request *r, t_auth_target *authtarget, t_authaction action); /**@brief Add client identified in request to client list. */ t_client* http_nodogsplash_add_client(request *r); /**@brief Serve a 307 Temporary Redirect */ void http_nodogsplash_redirect(request *r, char *url); /**@brief Serve the splash page from its file */ -void http_nodogsplash_serve_splash(request *r, char *token); +void http_nodogsplash_serve_splash(request *r, t_auth_target *authtarget); /**@brief Handle initial contact from client */ void http_nodogsplash_first_contact(request *r); /**@brief Decode token and redirect URL from a request */ -void http_nodogsplash_decode_authtarget(request *r, char **token, char **redir); +t_auth_target* http_nodogsplash_decode_authtarget(request *r); /**@brief Malloc and return a string that is the authenticating URL */ -char* http_nodogsplash_encode_authtarget(request *r, char *token); +char* http_nodogsplash_encode_authtarget(t_auth_target *authtarget); +/**@brief Malloc and return a t_auth_target struct encoding info */ +t_auth_target* http_nodogsplash_make_authtarget(char* token, char* redirhost, char* redirpath); +/**@brief Malloc and return a t_auth_target struct encoding info */ +t_auth_target* http_nodogsplash_make_authtarget_from_request(request *r); +/**@brief Free a t_auth_target struct */ +void http_nodogsplash_free_authtarget(t_auth_target* authtarget); /**@brief Allocate and return a random string of 8 hex digits suitable as an authentication token */ char * http_make_auth_token(); @@ -58,4 +79,6 @@ void http_nodogsplash_header(request *r, char *title); /** @brief Sends HTML footer to web browser */ void http_nodogsplash_footer(request *r); + + #endif /* _HTTP_H_ */ diff --git a/src/util.c b/src/util.c index 3a24b3b..5a38cc5 100644 --- a/src/util.c +++ b/src/util.c @@ -306,10 +306,21 @@ char * get_status_text() { config->gw_address, config->gw_port); len = strlen(buffer); - snprintf((buffer + len), (sizeof(buffer) - len), "Splashpage: %s/%s\n", - config->webroot, config->splashpage); - len = strlen(buffer); + if(config->authenticate_immediately) { + snprintf((buffer + len), (sizeof(buffer) - len), "Authenticate immediately: yes\n"); + len = strlen(buffer); + + } else { + snprintf((buffer + len), (sizeof(buffer) - len), "Splashpage: %s/%s\n", + config->webroot, config->splashpage); + len = strlen(buffer); + } + if(config->redirectURL) { + snprintf((buffer + len), (sizeof(buffer) - len), "Redirect URL: %s\n", + config->redirectURL); + len = strlen(buffer); + } snprintf((buffer + len), (sizeof(buffer) - len), "Traffic control: %s\n", config->traffic_control ? "yes" : "no"); len = strlen(buffer); @@ -405,7 +416,7 @@ char * get_status_text() { uptime -= minutes * 60; seconds = uptime; - snprintf((buffer + len), (sizeof(buffer) - len), "Active time: %ud %uh %um %us\n", days, hours, minutes, seconds); + snprintf((buffer + len), (sizeof(buffer) - len), " Active time: %ud %uh %um %us\n", days, hours, minutes, seconds); len = strlen(buffer); snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token ? first->token : "none");