mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
finished authentication, implemented port/dir protection
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@60 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
30a1970bb2
commit
36ac01f46a
@ -8,5 +8,7 @@ Changes since 1.0.0
|
|||||||
axhttpd Changes
|
axhttpd Changes
|
||||||
* Header file issue fixed (in mime_types.c)
|
* Header file issue fixed (in mime_types.c)
|
||||||
* chroot() now used for better security
|
* chroot() now used for better security
|
||||||
* Authentication implemented
|
* Basic authentication implemented (with .htpasswd)
|
||||||
*
|
* HTTP Port protection implemented (with .htaccess)
|
||||||
|
* Directory access protection implemented (with .htaccess)
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ CONFIG_HTTP_WEBROOT="../www"
|
|||||||
CONFIG_HTTP_PORT=80
|
CONFIG_HTTP_PORT=80
|
||||||
CONFIG_HTTP_TIMEOUT=5
|
CONFIG_HTTP_TIMEOUT=5
|
||||||
# CONFIG_HTTP_HAS_CGI is not set
|
# CONFIG_HTTP_HAS_CGI is not set
|
||||||
CONFIG_HTTP_CGI_EXTENSION=""
|
CONFIG_HTTP_CGI_EXTENSIONS=""
|
||||||
# CONFIG_HTTP_DIRECTORIES is not set
|
# CONFIG_HTTP_DIRECTORIES is not set
|
||||||
# CONFIG_HTTP_PERM_CHECK is not set
|
# CONFIG_HTTP_PERM_CHECK is not set
|
||||||
# CONFIG_HTTP_HAS_IPV6 is not set
|
# CONFIG_HTTP_HAS_IPV6 is not set
|
||||||
|
@ -59,7 +59,7 @@ CONFIG_HTTP_WEBROOT="www"
|
|||||||
CONFIG_HTTP_PORT=80
|
CONFIG_HTTP_PORT=80
|
||||||
CONFIG_HTTP_TIMEOUT=5
|
CONFIG_HTTP_TIMEOUT=5
|
||||||
# CONFIG_HTTP_HAS_CGI is not set
|
# CONFIG_HTTP_HAS_CGI is not set
|
||||||
CONFIG_HTTP_CGI_EXTENSION=""
|
CONFIG_HTTP_CGI_EXTENSIONS=""
|
||||||
CONFIG_HTTP_DIRECTORIES=y
|
CONFIG_HTTP_DIRECTORIES=y
|
||||||
# CONFIG_HTTP_PERM_CHECK is not set
|
# CONFIG_HTTP_PERM_CHECK is not set
|
||||||
# CONFIG_HTTP_HAS_IPV6 is not set
|
# CONFIG_HTTP_HAS_IPV6 is not set
|
||||||
|
@ -10,7 +10,7 @@ config CONFIG_HTTP_STATIC_BUILD
|
|||||||
bool "Static Build"
|
bool "Static Build"
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Select y if you want axhttp to be a static build (i.e. don't use the
|
Select y if you want axhttpd to be a static build (i.e. don't use the
|
||||||
axtls shared library or dll).
|
axtls shared library or dll).
|
||||||
|
|
||||||
config CONFIG_HTTP_PORT
|
config CONFIG_HTTP_PORT
|
||||||
@ -59,12 +59,14 @@ config CONFIG_HTTP_HAS_CGI
|
|||||||
help
|
help
|
||||||
Enable the CGI capability.
|
Enable the CGI capability.
|
||||||
|
|
||||||
config CONFIG_HTTP_CGI_EXTENSION
|
config CONFIG_HTTP_CGI_EXTENSIONS
|
||||||
string "CGI File Extension"
|
string "CGI File Extension(s)"
|
||||||
default ".php"
|
default ".php,.sh"
|
||||||
depends on CONFIG_HTTP_HAS_CGI
|
depends on CONFIG_HTTP_HAS_CGI
|
||||||
help
|
help
|
||||||
Tell axhhtp what file extension is used for CGI
|
Tell axhhtpd what file extension(s) are used for CGI.
|
||||||
|
|
||||||
|
This is a comma separated list.
|
||||||
|
|
||||||
config CONFIG_HTTP_DIRECTORIES
|
config CONFIG_HTTP_DIRECTORIES
|
||||||
bool "Enable Directory Listing"
|
bool "Enable Directory Listing"
|
||||||
|
@ -25,8 +25,10 @@ ifndef CONFIG_PLATFORM_WIN32
|
|||||||
|
|
||||||
ifdef CONFIG_PLATFORM_CYGWIN
|
ifdef CONFIG_PLATFORM_CYGWIN
|
||||||
TARGET=../$(STAGE)/axhttpd.exe
|
TARGET=../$(STAGE)/axhttpd.exe
|
||||||
|
TARGET2=../$(STAGE)/htpasswd.exe
|
||||||
else
|
else
|
||||||
TARGET=../$(STAGE)/axhttpd
|
TARGET=../$(STAGE)/axhttpd
|
||||||
|
TARGET2=../$(STAGE)/htpasswd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_HTTP_STATIC_BUILD
|
ifdef CONFIG_HTTP_STATIC_BUILD
|
||||||
@ -39,6 +41,7 @@ CFLAGS += -I../ssl
|
|||||||
|
|
||||||
else # win32 build
|
else # win32 build
|
||||||
TARGET=../$(STAGE)/axhttpd.exe
|
TARGET=../$(STAGE)/axhttpd.exe
|
||||||
|
TARGET2=../$(STAGE)/htpasswd.exe
|
||||||
|
|
||||||
ifdef CONFIG_HTTP_STATIC_BUILD
|
ifdef CONFIG_HTTP_STATIC_BUILD
|
||||||
LIBS=../$(STAGE)/axtls.static.lib ..\\config\\axtls.res
|
LIBS=../$(STAGE)/axtls.static.lib ..\\config\\axtls.res
|
||||||
@ -51,7 +54,11 @@ ifndef CONFIG_AXHTTPD
|
|||||||
web_server:
|
web_server:
|
||||||
else
|
else
|
||||||
|
|
||||||
web_server : $(TARGET)
|
web_server :: $(TARGET)
|
||||||
|
|
||||||
|
ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
|
web_server :: $(TARGET2)
|
||||||
|
endif
|
||||||
|
|
||||||
OBJ= \
|
OBJ= \
|
||||||
axhttpd.o \
|
axhttpd.o \
|
||||||
@ -69,14 +76,24 @@ ifndef CONFIG_PLATFORM_SOLARIS
|
|||||||
strip --remove-section=.comment $(TARGET)
|
strip --remove-section=.comment $(TARGET)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
$(TARGET2): htpasswd.o ../$(STAGE)/libaxtls.a
|
||||||
|
$(LD) $(LDFLAGS) -o $@ htpasswd.o $(LIBS)
|
||||||
|
|
||||||
else # Win32
|
else # Win32
|
||||||
|
|
||||||
OBJ:=$(OBJ:.o=.obj)
|
OBJ:=$(OBJ:.o=.obj)
|
||||||
%.obj : %.c
|
%.obj : %.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
|
|
||||||
|
htpasswd.obj : htpasswd.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
|
|
||||||
$(TARGET): $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
$(LD) $(LDFLAGS) $(LIBS) /out:$@ $(OBJ)
|
$(LD) $(LDFLAGS) $(LIBS) /out:$@ $(OBJ)
|
||||||
|
|
||||||
|
$(TARGET2): htpasswd.obj
|
||||||
|
$(LD) $(LDFLAGS) $(LIBS) /out:$@ $(OBJ)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif # CONFIG_AXHTTPD
|
endif # CONFIG_AXHTTPD
|
||||||
|
39
httpd/README
39
httpd/README
@ -4,3 +4,42 @@ axhttpd is a small embedded web server using the axTLS library.
|
|||||||
It is based originally on the web server written by Doug Currie which is at:
|
It is based originally on the web server written by Doug Currie which is at:
|
||||||
http://www.hcsw.org/awhttpd.
|
http://www.hcsw.org/awhttpd.
|
||||||
|
|
||||||
|
Basic Authentication
|
||||||
|
====================
|
||||||
|
|
||||||
|
Basic Authentication uses a password file called ".htpasswd", in the
|
||||||
|
directory to be protected. This file is formatted as the familiar
|
||||||
|
colon-separated username/encrypted-password pair, records delimited by
|
||||||
|
newlines. The protection does not carry over to subdirectories. The
|
||||||
|
utility program htpasswd is included to help manually edit .htpasswd files.
|
||||||
|
|
||||||
|
The encryption of this password uses a proprietary algorithm due to the
|
||||||
|
dependency of many crypt libraries on DES.
|
||||||
|
|
||||||
|
An example is in /test_dir/prot (username 'abcd', password is '1234').
|
||||||
|
|
||||||
|
Note: This is an mconf configuration option.
|
||||||
|
|
||||||
|
HTTP Port Protection
|
||||||
|
====================
|
||||||
|
|
||||||
|
Directories/files can be accessed using the 'http' or 'https' uri prefix. If
|
||||||
|
normal http access for a directory needs to be disabled, then put
|
||||||
|
"SSLRequireSSL" into a '.htaccess' file in the directory to be protected.
|
||||||
|
|
||||||
|
An example is in /test_dir/prot.
|
||||||
|
|
||||||
|
CGI
|
||||||
|
===
|
||||||
|
|
||||||
|
chroot() is now used for added security. However this has the impact of
|
||||||
|
removing the regular filesystem, so any CGI applications no longer have the
|
||||||
|
usual access.
|
||||||
|
|
||||||
|
So any executables and libraries need to be copied into webroot (under /bin
|
||||||
|
and /lib).
|
||||||
|
|
||||||
|
Failure to do so will result in mystical blank screens (and probably hundreds
|
||||||
|
of axhttpd instances being created...).
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,9 +25,7 @@
|
|||||||
#define HAVE_IPV6
|
#define HAVE_IPV6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAXFILEPATH 1024
|
#define MAXREQUESTLENGTH 256
|
||||||
#define MAXIPLEN 45
|
|
||||||
#define MAXREQUESTLENGTH 1024
|
|
||||||
#define MAXCGIARGS 100
|
#define MAXCGIARGS 100
|
||||||
#define BLOCKSIZE 4096
|
#define BLOCKSIZE 4096
|
||||||
|
|
||||||
@ -40,9 +38,12 @@
|
|||||||
#define STATE_WANT_TO_SEND_FILE 4
|
#define STATE_WANT_TO_SEND_FILE 4
|
||||||
#define STATE_DOING_DIR 5
|
#define STATE_DOING_DIR 5
|
||||||
|
|
||||||
#define TYPE_GET 0
|
enum
|
||||||
#define TYPE_HEAD 1
|
{
|
||||||
#define TYPE_POST 2
|
TYPE_GET,
|
||||||
|
TYPE_HEAD,
|
||||||
|
TYPE_POST
|
||||||
|
};
|
||||||
|
|
||||||
struct connstruct
|
struct connstruct
|
||||||
{
|
{
|
||||||
@ -62,21 +63,21 @@ struct connstruct
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
time_t timeout;
|
time_t timeout;
|
||||||
char ip[MAXIPLEN];
|
|
||||||
char actualfile[MAXREQUESTLENGTH];
|
char actualfile[MAXREQUESTLENGTH];
|
||||||
char filereq[MAXREQUESTLENGTH];
|
char filereq[MAXREQUESTLENGTH];
|
||||||
|
char dirname[MAXREQUESTLENGTH];
|
||||||
|
char virtualhostreq[MAXREQUESTLENGTH];
|
||||||
|
int numbytes;
|
||||||
|
char databuf[BLOCKSIZE];
|
||||||
|
uint8_t is_ssl;
|
||||||
|
uint8_t close_when_done;
|
||||||
|
uint8_t modified_since;
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
char cgiargs[MAXREQUESTLENGTH];
|
char cgiargs[MAXREQUESTLENGTH];
|
||||||
char cgiscriptinfo[MAXREQUESTLENGTH];
|
char cgiscriptinfo[MAXREQUESTLENGTH];
|
||||||
char cgipathinfo[MAXREQUESTLENGTH];
|
char cgipathinfo[MAXREQUESTLENGTH];
|
||||||
#endif
|
#endif
|
||||||
char virtualhostreq[MAXREQUESTLENGTH];
|
|
||||||
int numbytes;
|
|
||||||
char databuf[BLOCKSIZE];
|
|
||||||
|
|
||||||
uint8_t is_ssl;
|
|
||||||
uint8_t close_when_done;
|
|
||||||
uint8_t modified_since;
|
|
||||||
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
||||||
char authorization[MAXREQUESTLENGTH];
|
char authorization[MAXREQUESTLENGTH];
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,7 +38,7 @@ static void procpermcheck(const char *pathtocheck);
|
|||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
struct cgiextstruct *cgiexts;
|
struct cgiextstruct *cgiexts;
|
||||||
static void addcgiext(char *tp);
|
static void addcgiext(const char *tp);
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
static void reaper(int sigtype)
|
static void reaper(int sigtype)
|
||||||
@ -55,6 +55,7 @@ static void sigint_cleanup(int sig)
|
|||||||
struct connstruct *tp;
|
struct connstruct *tp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
while (servers != NULL)
|
while (servers != NULL)
|
||||||
{
|
{
|
||||||
if (servers->is_ssl)
|
if (servers->is_ssl)
|
||||||
@ -75,6 +76,17 @@ static void sigint_cleanup(int sig)
|
|||||||
freeconns = tp;
|
freeconns = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
while (cgiexts)
|
||||||
|
{
|
||||||
|
struct cgiextstruct *cp = cgiexts->next;
|
||||||
|
if (cp == NULL) /* last entry */
|
||||||
|
free(cgiexts->ext);
|
||||||
|
free(cgiexts);
|
||||||
|
cgiexts = cp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +171,7 @@ int main(int argc, char *argv[])
|
|||||||
procpermcheck(webroot);
|
procpermcheck(webroot);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
addcgiext(CONFIG_HTTP_CGI_EXTENSION);
|
addcgiext(CONFIG_HTTP_CGI_EXTENSIONS);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_HTTP_VERBOSE)
|
#if defined(CONFIG_HTTP_VERBOSE)
|
||||||
printf("axhttpd (%s): listening on ports %d (http) and %d (https)\n",
|
printf("axhttpd (%s): listening on ports %d (http) and %d (https)\n",
|
||||||
@ -413,13 +425,21 @@ static void procpermcheck(const char *pathtocheck)
|
|||||||
#endif /* CONFIG_HTTP_PERM_CHECK */
|
#endif /* CONFIG_HTTP_PERM_CHECK */
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
static void addcgiext(char *tp)
|
static void addcgiext(const char *cgi_exts)
|
||||||
{
|
{
|
||||||
struct cgiextstruct *ex = (struct cgiextstruct *)
|
char *cp = strdup(cgi_exts);
|
||||||
malloc(sizeof(struct cgiextstruct));
|
|
||||||
ex->ext = strdup(tp);
|
/* extenstions are comma separated */
|
||||||
ex->next = cgiexts;
|
do
|
||||||
cgiexts = ex;
|
{
|
||||||
|
struct cgiextstruct *ex = (struct cgiextstruct *)
|
||||||
|
malloc(sizeof(struct cgiextstruct));
|
||||||
|
ex->ext = cp;
|
||||||
|
ex->next = cgiexts;
|
||||||
|
cgiexts = ex;
|
||||||
|
if ((cp = strchr(cp, ',')) != NULL)
|
||||||
|
*cp++ = 0;
|
||||||
|
} while (cp != NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -557,10 +577,8 @@ static void addconnection(int sd, char *ip, int is_ssl)
|
|||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
*(tp->cgiargs) = '\0';
|
*(tp->cgiargs) = '\0';
|
||||||
#endif
|
#endif
|
||||||
*(tp->virtualhostreq) = '\0';
|
|
||||||
tp->state = STATE_WANT_TO_READ_HEAD;
|
tp->state = STATE_WANT_TO_READ_HEAD;
|
||||||
tp->reqtype = TYPE_GET;
|
tp->reqtype = TYPE_GET;
|
||||||
my_strncpy(tp->ip, ip, MAXIPLEN);
|
|
||||||
tp->close_when_done = 0;
|
tp->close_when_done = 0;
|
||||||
tp->modified_since = 0;
|
tp->modified_since = 0;
|
||||||
tp->timeout = time(NULL) + CONFIG_HTTP_TIMEOUT;
|
tp->timeout = time(NULL) + CONFIG_HTTP_TIMEOUT;
|
||||||
|
117
httpd/conn.c
117
httpd/conn.c
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright(C) 2006 Cameron Rich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "axhttp.h"
|
|
||||||
|
|
||||||
void addconnection(int sd, char *ip, int is_ssl)
|
|
||||||
{
|
|
||||||
struct connstruct *tp;
|
|
||||||
|
|
||||||
// Get ourselves a connstruct
|
|
||||||
if (freeconns == NULL)
|
|
||||||
tp = (struct connstruct *)malloc(sizeof(struct connstruct));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tp = freeconns;
|
|
||||||
freeconns = tp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach it to the used list
|
|
||||||
tp->next = usedconns;
|
|
||||||
usedconns = tp;
|
|
||||||
tp->networkdesc = sd;
|
|
||||||
|
|
||||||
if (is_ssl)
|
|
||||||
ssl_server_new(servers->ssl_ctx, sd);
|
|
||||||
tp->is_ssl = is_ssl;
|
|
||||||
tp->filedesc = -1;
|
|
||||||
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
|
||||||
tp->dirp = NULL;
|
|
||||||
#endif
|
|
||||||
*(tp->actualfile) = '\0';
|
|
||||||
*(tp->filereq) = '\0';
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
|
||||||
*(tp->cgiargs) = '\0';
|
|
||||||
#endif
|
|
||||||
*(tp->virtualhostreq) = '\0';
|
|
||||||
tp->state = STATE_WANT_TO_READ_HEAD;
|
|
||||||
tp->reqtype = TYPE_GET;
|
|
||||||
my_strncpy(tp->ip, ip, MAXIPLEN);
|
|
||||||
tp->close_when_done = 0;
|
|
||||||
tp->modified_since = 0;
|
|
||||||
tp->timeout = time(NULL) + CONFIG_HTTP_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeconnection(struct connstruct *cn)
|
|
||||||
{
|
|
||||||
struct connstruct *tp;
|
|
||||||
int shouldret = 0;
|
|
||||||
|
|
||||||
tp = usedconns;
|
|
||||||
|
|
||||||
if (tp == NULL || cn == NULL)
|
|
||||||
shouldret = 1;
|
|
||||||
else if (tp == cn)
|
|
||||||
usedconns = tp->next;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (tp != NULL)
|
|
||||||
{
|
|
||||||
if (tp->next == cn)
|
|
||||||
{
|
|
||||||
tp->next = (tp->next)->next;
|
|
||||||
shouldret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp = tp->next;
|
|
||||||
shouldret = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If we did, add it to the free list
|
|
||||||
cn->next = freeconns;
|
|
||||||
freeconns = cn;
|
|
||||||
|
|
||||||
// Close it all down
|
|
||||||
if (cn->networkdesc != -1)
|
|
||||||
{
|
|
||||||
if (cn->is_ssl)
|
|
||||||
ssl_free(ssl_find(servers->ssl_ctx, cn->networkdesc));
|
|
||||||
|
|
||||||
SOCKET_CLOSE(cn->networkdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cn->filedesc != -1)
|
|
||||||
close(cn->filedesc);
|
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
|
||||||
if (cn->dirp != NULL)
|
|
||||||
#ifdef WIN32
|
|
||||||
FindClose(cn->dirp);
|
|
||||||
#else
|
|
||||||
closedir(cn->dirp);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
98
httpd/htpasswd.c
Normal file
98
httpd/htpasswd.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2007 Cameron Rich
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ssl.h"
|
||||||
|
|
||||||
|
int tfd;
|
||||||
|
|
||||||
|
void base64_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen)
|
||||||
|
{
|
||||||
|
static const char b64str[64] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
while (inlen && outlen)
|
||||||
|
{
|
||||||
|
*out++ = b64str[(in[0] >> 2) & 0x3f];
|
||||||
|
if (!--outlen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*out++ = b64str[((in[0] << 4)
|
||||||
|
+ (--inlen ? in[1] >> 4 : 0)) & 0x3f];
|
||||||
|
if (!--outlen)
|
||||||
|
break;
|
||||||
|
*out++ = (inlen
|
||||||
|
? b64str[((in[1] << 2)
|
||||||
|
+ (--inlen ? in[2] >> 6 : 0))
|
||||||
|
& 0x3f]
|
||||||
|
: '=');
|
||||||
|
if (!--outlen)
|
||||||
|
break;
|
||||||
|
*out++ = inlen ? b64str[in[2] & 0x3f] : '=';
|
||||||
|
if (!--outlen)
|
||||||
|
break;
|
||||||
|
if (inlen)
|
||||||
|
inlen--;
|
||||||
|
if (inlen)
|
||||||
|
in += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outlen)
|
||||||
|
*out = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Usage: htpasswd username\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char* pw;
|
||||||
|
uint8_t md5_salt[MD5_SIZE], md5_pass[MD5_SIZE];
|
||||||
|
char b64_salt[MD5_SIZE+10], b64_pass[MD5_SIZE+10];
|
||||||
|
MD5_CTX ctx;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
pw = strdup(getpass("New password:"));
|
||||||
|
if (strcmp(pw, getpass("Re-type new password:")) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "They don't match, sorry.\n" );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
RNG_initialize(pw, sizeof(pw));
|
||||||
|
get_random(MD5_SIZE, md5_salt);
|
||||||
|
RNG_terminate();
|
||||||
|
base64_encode(md5_salt, MD5_SIZE, b64_salt, sizeof(b64_salt));
|
||||||
|
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, md5_salt, MD5_SIZE);
|
||||||
|
MD5Update(&ctx, pw, strlen(pw));
|
||||||
|
MD5Final(&ctx, md5_pass);
|
||||||
|
base64_encode(md5_pass, MD5_SIZE, b64_pass, sizeof(b64_pass));
|
||||||
|
|
||||||
|
printf("Add the following to your '.htpasswd' file\n");
|
||||||
|
printf("%s:%s$%s\n", argv[1], b64_salt, b64_pass);
|
||||||
|
return 0;
|
||||||
|
}
|
201
httpd/proc.c
201
httpd/proc.c
@ -35,6 +35,7 @@ static void urldecode(char *buf);
|
|||||||
static void buildactualfile(struct connstruct *cn);
|
static void buildactualfile(struct connstruct *cn);
|
||||||
static int sanitizefile(const char *buf);
|
static int sanitizefile(const char *buf);
|
||||||
static int sanitizehost(char *buf);
|
static int sanitizehost(char *buf);
|
||||||
|
static int htaccess_check(struct connstruct *cn);
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
static void urlencode(const uint8_t *s, uint8_t *t);
|
static void urlencode(const uint8_t *s, uint8_t *t);
|
||||||
@ -63,11 +64,10 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
|
|
||||||
*delim = 0;
|
*delim = 0;
|
||||||
value = delim+1;
|
value = delim+1;
|
||||||
printf("BUF %s - value %s\n", buf, value);
|
|
||||||
|
|
||||||
if (strcmp(buf, "GET") == 0 ||
|
/* printf("name: %s, value: %s\n", buf, value); */
|
||||||
strcmp(buf, "HEAD") == 0 ||
|
if (strcmp(buf, "GET") == 0 || strcmp(buf, "HEAD") == 0 ||
|
||||||
strcmp(buf, "POST") == 0)
|
strcmp(buf, "POST") == 0)
|
||||||
{
|
{
|
||||||
if (buf[0] == 'H')
|
if (buf[0] == 'H')
|
||||||
cn->reqtype = TYPE_HEAD;
|
cn->reqtype = TYPE_HEAD;
|
||||||
@ -76,13 +76,13 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
|
|
||||||
if ((delim = strchr(value, ' ')) == NULL) /* expect HTTP type */
|
if ((delim = strchr(value, ' ')) == NULL) /* expect HTTP type */
|
||||||
return 0;
|
return 0;
|
||||||
*delim = 0;
|
|
||||||
|
|
||||||
|
*delim = 0;
|
||||||
urldecode(value);
|
urldecode(value);
|
||||||
|
|
||||||
if (sanitizefile(value) == 0)
|
if (sanitizefile(value) == 0)
|
||||||
{
|
{
|
||||||
send_error(cn, 404);
|
send_error(cn, 403);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,6 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
my_strncpy(cn->cgiargs, value+1, MAXREQUESTLENGTH);
|
my_strncpy(cn->cgiargs, value+1, MAXREQUESTLENGTH);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(buf, "Host:") == 0)
|
else if (strcmp(buf, "Host:") == 0)
|
||||||
{
|
{
|
||||||
@ -117,11 +116,14 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
else if (strcmp(buf, "Authorization:") == 0 &&
|
else if (strcmp(buf, "Authorization:") == 0 &&
|
||||||
strncmp(value, "Basic ", 6) == 0)
|
strncmp(value, "Basic ", 6) == 0)
|
||||||
{
|
{
|
||||||
|
int size;
|
||||||
if (base64_decode(&value[6], strlen(&value[6]),
|
if (base64_decode(&value[6], strlen(&value[6]),
|
||||||
cn->authorization, NULL))
|
cn->authorization, &size))
|
||||||
cn->authorization[0] = 0; /* error */
|
cn->authorization[0] = 0; /* error */
|
||||||
|
else
|
||||||
|
cn->authorization[size] = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -319,36 +321,42 @@ void procsendhead(struct connstruct *cn)
|
|||||||
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
||||||
char date[32];
|
char date[32];
|
||||||
|
|
||||||
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
/* are we trying to access a file over the HTTP connection instead of a
|
||||||
if (auth_check(cn))
|
* HTTPS connection? Or is this directory disabled? */
|
||||||
|
if (htaccess_check(cn))
|
||||||
{
|
{
|
||||||
|
send_error(cn, 403);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
|
if (auth_check(cn)) /* see if there is a '.htpasswd' file */
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
printf("axhttpd: access to %s denied\n", cn->actualfile); TTY_FLUSH();
|
||||||
|
#endif
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy(date, ctime(&now));
|
if (stat(cn->actualfile, &stbuf) == -1)
|
||||||
|
|
||||||
if (stat(cn->actualfile, &stbuf) == -1)
|
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
if (trycgi_withpathinfo(cn) == 0)
|
if (stat(cn->actualfile, &stbuf) == -1 && trycgi_withpathinfo(cn) == 0)
|
||||||
{
|
{
|
||||||
/* We Try To Find A CGI */
|
/* We Try To Find A CGI */
|
||||||
proccgi(cn, 1);
|
proccgi(cn, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send_error(cn, 404);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
if (iscgi(cn->actualfile))
|
if (iscgi(cn->actualfile))
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
/* Set up CGI script */
|
/* An executable file? */
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
{
|
{
|
||||||
send_error(cn, 404);
|
send_error(cn, 404);
|
||||||
@ -396,6 +404,8 @@ void procsendhead(struct connstruct *cn)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy(date, ctime(&now));
|
||||||
|
|
||||||
if (cn->modified_since)
|
if (cn->modified_since)
|
||||||
{
|
{
|
||||||
/* file has already been read before */
|
/* file has already been read before */
|
||||||
@ -407,20 +417,6 @@ void procsendhead(struct connstruct *cn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
|
||||||
printf("axhttpd: %s send %s\n",
|
|
||||||
cn->is_ssl ? "https" : "http", cn->actualfile);
|
|
||||||
TTY_FLUSH();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n"
|
|
||||||
"Content-Type: %s\nContent-Length: %ld\n"
|
|
||||||
"Date: %sLast-Modified: %s\n", VERSION,
|
|
||||||
getmimetype(cn->actualfile), (long) stbuf.st_size,
|
|
||||||
date, ctime(&(stbuf.st_mtime))); /* ctime() has a \n on the end */
|
|
||||||
|
|
||||||
special_write(cn, buf, strlen(buf));
|
|
||||||
|
|
||||||
if (cn->reqtype == TYPE_HEAD)
|
if (cn->reqtype == TYPE_HEAD)
|
||||||
{
|
{
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
@ -437,10 +433,23 @@ void procsendhead(struct connstruct *cn)
|
|||||||
if (cn->filedesc == -1)
|
if (cn->filedesc == -1)
|
||||||
{
|
{
|
||||||
send_error(cn, 404);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n"
|
||||||
|
"Content-Type: %s\nContent-Length: %ld\n"
|
||||||
|
"Date: %sLast-Modified: %s\n", VERSION,
|
||||||
|
getmimetype(cn->actualfile), (long) stbuf.st_size,
|
||||||
|
date, ctime(&(stbuf.st_mtime))); /* ctime() has a \n on the end */
|
||||||
|
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
printf("axhttpd: %s send %s\n",
|
||||||
|
cn->is_ssl ? "https" : "http", cn->actualfile);
|
||||||
|
TTY_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -659,10 +668,8 @@ static int trycgi_withpathinfo(struct connstruct *cn)
|
|||||||
/* We've found our CGI file! */
|
/* We've found our CGI file! */
|
||||||
my_strncpy(cn->actualfile, tpfile, MAXREQUESTLENGTH);
|
my_strncpy(cn->actualfile, tpfile, MAXREQUESTLENGTH);
|
||||||
my_strncpy(cn->cgiscriptinfo, fr_str, MAXREQUESTLENGTH);
|
my_strncpy(cn->cgiscriptinfo, fr_str, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
offset = (fr_rs[i] + strlen(fr_rs[i])) - fr_str;
|
offset = (fr_rs[i] + strlen(fr_rs[i])) - fr_str;
|
||||||
my_strncpy(cn->cgipathinfo, cn->filereq+offset, MAXREQUESTLENGTH);
|
my_strncpy(cn->cgipathinfo, cn->filereq+offset, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,11 +685,10 @@ static int trycgi_withpathinfo(struct connstruct *cn)
|
|||||||
|
|
||||||
static int iscgi(const char *fn)
|
static int iscgi(const char *fn)
|
||||||
{
|
{
|
||||||
struct cgiextstruct *tp;
|
struct cgiextstruct *tp = cgiexts;
|
||||||
int fnlen, extlen;
|
int fnlen, extlen;
|
||||||
|
|
||||||
fnlen = strlen(fn);
|
fnlen = strlen(fn);
|
||||||
tp = cgiexts;
|
|
||||||
|
|
||||||
while (tp != NULL)
|
while (tp != NULL)
|
||||||
{
|
{
|
||||||
@ -784,6 +790,7 @@ static int hexit(char c)
|
|||||||
|
|
||||||
static void buildactualfile(struct connstruct *cn)
|
static void buildactualfile(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
|
char *cp;
|
||||||
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s", cn->filereq);
|
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s", cn->filereq);
|
||||||
|
|
||||||
/* Add directory slash if not there */
|
/* Add directory slash if not there */
|
||||||
@ -791,12 +798,23 @@ static void buildactualfile(struct connstruct *cn)
|
|||||||
cn->actualfile[strlen(cn->actualfile)-1] != '/')
|
cn->actualfile[strlen(cn->actualfile)-1] != '/')
|
||||||
strcat(cn->actualfile, "/");
|
strcat(cn->actualfile, "/");
|
||||||
|
|
||||||
|
/* work out the directory name */
|
||||||
|
strncpy(cn->dirname, cn->actualfile, MAXREQUESTLENGTH);
|
||||||
|
if ((cp = strrchr(cn->dirname, '/')) == NULL)
|
||||||
|
cn->dirname[0] = 0;
|
||||||
|
else
|
||||||
|
*cp = 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* convert all the forward slashes to back slashes */
|
/* convert all the forward slashes to back slashes */
|
||||||
{
|
{
|
||||||
char *t = cn->actualfile;
|
char *t = cn->actualfile;
|
||||||
while ((t = strchr(t, '/')))
|
while ((t = strchr(t, '/')))
|
||||||
*t++ = '\\';
|
*t++ = '\\';
|
||||||
|
|
||||||
|
t = cn->dirname;
|
||||||
|
while ((t = strchr(t, '/')))
|
||||||
|
*t++ = '\\';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -844,9 +862,14 @@ static int sanitizehost(char *buf)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
static FILE * exist_check(struct connstruct *cn, const char *check_file)
|
||||||
#define AUTH_FILE ".htpasswd"
|
{
|
||||||
|
char pathname[MAXREQUESTLENGTH];
|
||||||
|
snprintf(pathname, MAXREQUESTLENGTH, "%s/%s", cn->dirname, check_file);
|
||||||
|
return fopen(pathname, "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
static void send_authenticate(struct connstruct *cn, const char *realm)
|
static void send_authenticate(struct connstruct *cn, const char *realm)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@ -857,30 +880,29 @@ static void send_authenticate(struct connstruct *cn, const char *realm)
|
|||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_digest(char *b64_file_passwd, const char *msg_passwd)
|
static int check_digest(char *salt, const char *msg_passwd)
|
||||||
{
|
{
|
||||||
uint8_t real_salt[MAXREQUESTLENGTH];
|
uint8_t b256_salt[MAXREQUESTLENGTH];
|
||||||
uint8_t real_passwd[MAXREQUESTLENGTH];
|
uint8_t real_passwd[MD5_SIZE];
|
||||||
int real_passwd_size, real_salt_size;
|
int salt_size;
|
||||||
char *b64_pwd;
|
char *b64_passwd;
|
||||||
uint8_t md5_result[MD5_SIZE];
|
uint8_t md5_result[MD5_SIZE];
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
|
|
||||||
/* retrieve the salt */
|
/* retrieve the salt */
|
||||||
if ((b64_pwd = strchr(b64_file_passwd, '$')) == NULL)
|
if ((b64_passwd = strchr(salt, '$')) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*b64_pwd++ = 0;
|
*b64_passwd++ = 0;
|
||||||
if (base64_decode(b64_file_passwd, strlen(b64_file_passwd),
|
if (base64_decode(salt, strlen(salt), b256_salt, &salt_size))
|
||||||
real_salt, &real_salt_size))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (base64_decode(b64_pwd, strlen(b64_pwd), real_passwd, &real_passwd_size))
|
if (base64_decode(b64_passwd, strlen(b64_passwd), real_passwd, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* very simple MD5 crypt algorithm, but then the salt we use is large */
|
/* very simple MD5 crypt algorithm, but then the salt we use is large */
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
MD5Update(&ctx, real_salt, real_salt_size); /* process the salt */
|
MD5Update(&ctx, b256_salt, salt_size); /* process the salt */
|
||||||
MD5Update(&ctx, msg_passwd, strlen(msg_passwd)); /* process the password */
|
MD5Update(&ctx, msg_passwd, strlen(msg_passwd)); /* process the password */
|
||||||
MD5Final(&ctx, md5_result);
|
MD5Final(&ctx, md5_result);
|
||||||
return memcmp(md5_result, real_passwd, MD5_SIZE);/* 0 = ok */
|
return memcmp(md5_result, real_passwd, MD5_SIZE);/* 0 = ok */
|
||||||
@ -888,36 +910,15 @@ static int check_digest(char *b64_file_passwd, const char *msg_passwd)
|
|||||||
|
|
||||||
static int auth_check(struct connstruct *cn)
|
static int auth_check(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char dirname[MAXREQUESTLENGTH];
|
|
||||||
char authpath[MAXREQUESTLENGTH];
|
|
||||||
char line[MAXREQUESTLENGTH];
|
char line[MAXREQUESTLENGTH];
|
||||||
|
FILE *fp;
|
||||||
char *cp;
|
char *cp;
|
||||||
FILE *fp = NULL;
|
|
||||||
struct stat auth_stat;
|
|
||||||
|
|
||||||
strncpy(dirname, cn->actualfile, MAXREQUESTLENGTH);
|
if ((fp = exist_check(cn, ".htpasswd")) == NULL)
|
||||||
cp = strrchr(dirname, '/');
|
return 0; /* no .htpasswd file, so let though */
|
||||||
if (cp == NULL)
|
|
||||||
dirname[0] = 0;
|
|
||||||
else
|
|
||||||
*cp = 0;
|
|
||||||
|
|
||||||
/* check that the file is not the AUTH_FILE itself */
|
|
||||||
if (strcmp(cn->actualfile, AUTH_FILE) == 0)
|
|
||||||
{
|
|
||||||
send_error(cn, 403);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(authpath, MAXREQUESTLENGTH, "%s/%s", dirname, AUTH_FILE);
|
|
||||||
if (stat(authpath, &auth_stat) < 0) /* no auth file, so let though */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (cn->authorization[0] == 0)
|
if (cn->authorization[0] == 0)
|
||||||
{
|
goto error;
|
||||||
send_authenticate(cn, dirname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cn->authorization is in form "username:password" */
|
/* cn->authorization is in form "username:password" */
|
||||||
if ((cp = strchr(cn->authorization, ':')) == NULL)
|
if ((cp = strchr(cn->authorization, ':')) == NULL)
|
||||||
@ -925,8 +926,6 @@ static int auth_check(struct connstruct *cn)
|
|||||||
else
|
else
|
||||||
*cp++ = 0; /* cp becomes the password */
|
*cp++ = 0; /* cp becomes the password */
|
||||||
|
|
||||||
fp = fopen(authpath, "r");
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL)
|
while (fgets(line, sizeof(line), fp) != NULL)
|
||||||
{
|
{
|
||||||
char *b64_file_passwd;
|
char *b64_file_passwd;
|
||||||
@ -952,14 +951,41 @@ static int auth_check(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
send_authenticate(cn, dirname);
|
fclose(fp);
|
||||||
|
send_authenticate(cn, cn->virtualhostreq);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int htaccess_check(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char line[MAXREQUESTLENGTH];
|
||||||
|
FILE *fp;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((fp = exist_check(cn, ".htaccess")) == NULL)
|
||||||
|
return 0; /* no .htaccess file, so let though */
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), fp) != NULL)
|
||||||
|
{
|
||||||
|
if (!cn->is_ssl && strstr(line, "SSLRequireSSL"))
|
||||||
|
{
|
||||||
|
ret = -1; /* SSL port access required */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(line, "Deny all"))
|
||||||
|
{
|
||||||
|
ret = -1; /* access to this dir denied */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_error(struct connstruct *cn, int err)
|
static void send_error(struct connstruct *cn, int err)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@ -971,6 +997,10 @@ static void send_error(struct connstruct *cn, int err)
|
|||||||
case 403:
|
case 403:
|
||||||
title = "Forbidden";
|
title = "Forbidden";
|
||||||
text = "File is protected";
|
text = "File is protected";
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
printf("axhttpd: access to %s:/%s denied\n",
|
||||||
|
cn->is_ssl ? "https" : "http", cn->actualfile); TTY_FLUSH();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 404:
|
case 404:
|
||||||
@ -979,9 +1009,12 @@ static void send_error(struct connstruct *cn, int err)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(buf, "HTTP/1.1 %d %s\nContent-Type: text/html\n"
|
sprintf(buf, "HTTP/1.1 %d %s\n"
|
||||||
"<html><body>\n<title>%d %s</title>"
|
"Content-Type: text/html\n"
|
||||||
"<h1>%d %s</h1>\n</body></html>\n",
|
"Cache-Control: no-cache,no-store\n"
|
||||||
|
"Connection: close\n\n"
|
||||||
|
"<html>\n<head>\n<title>%d %s</title></head>\n"
|
||||||
|
"<body><h1>%d %s</h1>\n</body></html>\n",
|
||||||
err, title, err, title, err, text);
|
err, title, err, title, err, text);
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
|
@ -99,5 +99,5 @@ endif
|
|||||||
|
|
||||||
clean::
|
clean::
|
||||||
$(MAKE) -C test clean
|
$(MAKE) -C test clean
|
||||||
-@rm -f ../$(STAGE)/*.pch ../$(STAGE)/*.so* ../$(STAGE)/*.a ../$(STAGE)/*.dll ../$(STAGE)/*.lib ../$(STAGE)/*.exp ../$(STAGE)/*.pdb ../$(STAGE)/*.ilk
|
-@rm -f ../$(STAGE)/* *.a *.lib
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* RNG declarations
|
* RNG declarations
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void RNG_initialize(const uint8_t *seed_buf, int size);
|
EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size);
|
||||||
void RNG_terminate(void);
|
EXP_FUNC void STDCALL RNG_terminate(void);
|
||||||
void get_random(int num_rand_bytes, uint8_t *rand_data);
|
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
|
||||||
void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
@ -270,7 +270,7 @@ typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key,
|
|||||||
int get_file(const char *filename, uint8_t **buf);
|
int get_file(const char *filename, uint8_t **buf);
|
||||||
|
|
||||||
#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
|
#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
|
||||||
void print_blob(const char *format, const uint8_t *data, int size, ...);
|
EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...);
|
||||||
#else
|
#else
|
||||||
#define print_blob(...)
|
#define print_blob(...)
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +82,7 @@ int get_file(const char *filename, uint8_t **buf)
|
|||||||
* - On Linux use /dev/urandom
|
* - On Linux use /dev/urandom
|
||||||
* - If none of these work then use a custom RNG.
|
* - If none of these work then use a custom RNG.
|
||||||
*/
|
*/
|
||||||
void RNG_initialize(const uint8_t *seed_buf, int size)
|
EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size)
|
||||||
{
|
{
|
||||||
if (rng_ref_count == 0)
|
if (rng_ref_count == 0)
|
||||||
{
|
{
|
||||||
@ -106,9 +106,7 @@ void RNG_initialize(const uint8_t *seed_buf, int size)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < size/(int)sizeof(uint64_t); i++)
|
for (i = 0; i < size/(int)sizeof(uint64_t); i++)
|
||||||
{
|
|
||||||
rng_num ^= *((uint64_t *)&seed_buf[i*sizeof(uint64_t)]);
|
rng_num ^= *((uint64_t *)&seed_buf[i*sizeof(uint64_t)]);
|
||||||
}
|
|
||||||
|
|
||||||
srand((long)seed_buf); /* use the stack ptr as another rnd seed */
|
srand((long)seed_buf); /* use the stack ptr as another rnd seed */
|
||||||
#endif
|
#endif
|
||||||
@ -120,7 +118,7 @@ void RNG_initialize(const uint8_t *seed_buf, int size)
|
|||||||
/**
|
/**
|
||||||
* Terminate the RNG engine.
|
* Terminate the RNG engine.
|
||||||
*/
|
*/
|
||||||
void RNG_terminate(void)
|
EXP_FUNC void STDCALL RNG_terminate(void)
|
||||||
{
|
{
|
||||||
if (--rng_ref_count == 0)
|
if (--rng_ref_count == 0)
|
||||||
{
|
{
|
||||||
@ -135,7 +133,7 @@ void RNG_terminate(void)
|
|||||||
/**
|
/**
|
||||||
* Set a series of bytes with a random number. Individual bytes can be 0
|
* Set a series of bytes with a random number. Individual bytes can be 0
|
||||||
*/
|
*/
|
||||||
void get_random(int num_rand_bytes, uint8_t *rand_data)
|
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
|
||||||
{
|
{
|
||||||
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
|
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
|
||||||
/* use the Linux default */
|
/* use the Linux default */
|
||||||
@ -160,9 +158,7 @@ void get_random(int num_rand_bytes, uint8_t *rand_data)
|
|||||||
|
|
||||||
memcpy(rand_data, &big_num1, sizeof(uint64_t));
|
memcpy(rand_data, &big_num1, sizeof(uint64_t));
|
||||||
if (num_rand_bytes > sizeof(uint64_t))
|
if (num_rand_bytes > sizeof(uint64_t))
|
||||||
{
|
|
||||||
memcpy(&rand_data[8], &big_num2, sizeof(uint64_t));
|
memcpy(&rand_data[8], &big_num2, sizeof(uint64_t));
|
||||||
}
|
|
||||||
|
|
||||||
if (num_rand_bytes > 16)
|
if (num_rand_bytes > 16)
|
||||||
{
|
{
|
||||||
@ -189,9 +185,7 @@ void get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
|
|||||||
for (i = 0; i < num_rand_bytes; i++)
|
for (i = 0; i < num_rand_bytes; i++)
|
||||||
{
|
{
|
||||||
while (rand_data[i] == 0) /* can't be 0 */
|
while (rand_data[i] == 0) /* can't be 0 */
|
||||||
{
|
|
||||||
rand_data[i] = (uint8_t)(rand());
|
rand_data[i] = (uint8_t)(rand());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +237,7 @@ static void print_hex(uint8_t hex)
|
|||||||
* @param data [in] The start of data to use
|
* @param data [in] The start of data to use
|
||||||
* @param ... [in] Any additional arguments
|
* @param ... [in] Any additional arguments
|
||||||
*/
|
*/
|
||||||
void print_blob(const char *format,
|
EXP_FUNC void STDCALL print_blob(const char *format,
|
||||||
const uint8_t *data, int size, ...)
|
const uint8_t *data, int size, ...)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -264,7 +258,7 @@ void print_blob(const char *format,
|
|||||||
}
|
}
|
||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
/* VC6.0 doesn't handle variadic macros */
|
/* VC6.0 doesn't handle variadic macros */
|
||||||
void print_blob(const char *format, const unsigned char *data,
|
EXP_FUNC void STDCALL print_blob(const char *format, const unsigned char *data,
|
||||||
int size, ...) {}
|
int size, ...) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
echo "Content-Type: text/html"
|
echo "Content-Type: text/html"
|
||||||
echo
|
echo
|
||||||
echo "<html><title>System Health</title><body>"
|
echo "<html><title>System Health</title><body>"
|
||||||
echo "<h1>System Health for '`hostname`'</h1>"
|
echo "<h1>System Health for '`/bin/hostname`'</h1>"
|
||||||
echo "<h2>Processes</h2><table border=\"2\">"
|
echo "<h2>Processes</h2><table border=\"2\">"
|
||||||
ps -ef | sed -e "s/\(.*\)/<tr><td>\1<\/td><\/tr>/"
|
/bin/ps -ef | /bin/sed -e "s/\(.*\)/<tr><td>\1<\/td><\/tr>/"
|
||||||
echo "</table><h2>Free FileSystem Space</h2>"
|
echo "</table><h2>Free FileSystem Space</h2>"
|
||||||
echo "<table border=\"2\">"
|
echo "<table border=\"2\">"
|
||||||
df -h . | sed -e "s/\(.*\)/<tr><td>\1<\/td><\/tr>/"
|
/bin/df -h / | /bin/sed -e "s/\(.*\)/<tr><td>\1<\/td><\/tr>/"
|
||||||
echo "</table></body></html>"
|
echo "</table></body></html>"
|
||||||
|
2
www/test_dir/prot/.htaccess
Normal file
2
www/test_dir/prot/.htaccess
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
SSLRequireSSL
|
||||||
|
|
1
www/test_dir/prot/.htpasswd
Normal file
1
www/test_dir/prot/.htpasswd
Normal file
@ -0,0 +1 @@
|
|||||||
|
abcd:CQhgDPyy0rvEU8OMxnQIvg==$YdJfIKZimFLYxPf/rbnhtQ==
|
6
www/test_dir/prot/index.html
Normal file
6
www/test_dir/prot/index.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<head><title>axhttpd is running</title></head>
|
||||||
|
<body>
|
||||||
|
Looks like you got to this directory.
|
||||||
|
</body>
|
||||||
|
</htm>
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/php
|
#!/bin/php
|
||||||
|
|
||||||
<?
|
<?
|
||||||
phpinfo();
|
phpinfo();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user