mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
lots of changes for axhttpd
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@53 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
dabdec8fcc
commit
ce893c517d
@ -57,7 +57,6 @@ OBJ= \
|
|||||||
conn.o \
|
conn.o \
|
||||||
main.o \
|
main.o \
|
||||||
proc.o \
|
proc.o \
|
||||||
misc.o \
|
|
||||||
mime_types.o
|
mime_types.o
|
||||||
|
|
||||||
ifndef CONFIG_PLATFORM_WIN32
|
ifndef CONFIG_PLATFORM_WIN32
|
||||||
@ -71,6 +70,10 @@ endif
|
|||||||
endif
|
endif
|
||||||
else # Win32
|
else # Win32
|
||||||
|
|
||||||
|
OBJ:=$(OBJ:.o=.obj)
|
||||||
|
%.obj : %.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
|
|
||||||
$(TARGET): $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
$(LD) $(LDFLAGS) $(LIBS) /out:$@ $(OBJ)
|
$(LD) $(LDFLAGS) $(LIBS) /out:$@ $(OBJ)
|
||||||
endif
|
endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
axhttpd is a small embedded web server using the axTLS library.
|
axhttpd is a small embedded web server using the axTLS library.
|
||||||
|
|
||||||
It is based quite closely on the web server written by Doug Currie (original
|
It is based originally on the web server written by Doug Currie and is at:
|
||||||
version is here: http://www.hcsw.org/awhttpd).
|
http://www.hcsw.org/awhttpd).
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ struct connstruct
|
|||||||
int numbytes;
|
int numbytes;
|
||||||
char databuf[BLOCKSIZE];
|
char databuf[BLOCKSIZE];
|
||||||
|
|
||||||
unsigned char is_ssl;
|
uint8_t is_ssl;
|
||||||
unsigned char close_when_done;
|
uint8_t close_when_done;
|
||||||
unsigned char modified_since;
|
uint8_t modified_since;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct serverstruct
|
struct serverstruct
|
||||||
@ -95,12 +95,6 @@ struct cgiextstruct
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct indexstruct
|
|
||||||
{
|
|
||||||
struct indexstruct *next;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Global prototypes
|
// Global prototypes
|
||||||
extern struct serverstruct *servers;
|
extern struct serverstruct *servers;
|
||||||
extern struct connstruct *usedconns;
|
extern struct connstruct *usedconns;
|
||||||
@ -108,49 +102,25 @@ extern struct connstruct *freeconns;
|
|||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
extern struct cgiextstruct *cgiexts;
|
extern struct cgiextstruct *cgiexts;
|
||||||
#endif
|
#endif
|
||||||
extern struct indexstruct *indexlist;
|
|
||||||
|
|
||||||
// Conf global prototypes
|
// Conf global prototypes
|
||||||
extern char *webroot;
|
extern char *webroot;
|
||||||
extern int allowdirectorylisting;
|
|
||||||
extern int allowcgi;
|
|
||||||
extern int permcheck;
|
|
||||||
|
|
||||||
// conn.c prototypes
|
// conn.c prototypes
|
||||||
void addconnection(int sd, char *ip, int is_ssl);
|
void addconnection(int sd, char *ip, int is_ssl);
|
||||||
void removeconnection(struct connstruct *cn);
|
void removeconnection(struct connstruct *cn);
|
||||||
|
|
||||||
// proc.c prototypes
|
// proc.c prototypes
|
||||||
int procheadelem(struct connstruct *cn, char *buf);
|
|
||||||
void procdirlisting(struct connstruct *cn);
|
|
||||||
void procdodir(struct connstruct *cn);
|
void procdodir(struct connstruct *cn);
|
||||||
void procreadhead(struct connstruct *cn);
|
void procreadhead(struct connstruct *cn);
|
||||||
void procsendhead(struct connstruct *cn);
|
void procsendhead(struct connstruct *cn);
|
||||||
void procreadfile(struct connstruct *cn);
|
void procreadfile(struct connstruct *cn);
|
||||||
void procsendfile(struct connstruct *cn);
|
void procsendfile(struct connstruct *cn);
|
||||||
int special_write(struct connstruct *cn, const uint8_t *buf, size_t count);
|
|
||||||
|
|
||||||
// misc.c prototypes
|
// misc.c prototypes
|
||||||
void nada(int sigtype);
|
|
||||||
void die(int sigtype);
|
|
||||||
void reaper(int sigtype);
|
|
||||||
void stripcrlf(char *p);
|
|
||||||
char *my_strncpy(char *dest, const char *src, size_t n);
|
char *my_strncpy(char *dest, const char *src, size_t n);
|
||||||
#ifndef __HAVE_ARCH_STRNLEN
|
int isdir(const char *name);
|
||||||
size_t strnlen ( const char * str, size_t maxlen );
|
|
||||||
#endif
|
|
||||||
int iscgi(char *fn);
|
|
||||||
void split(char *tp, char *sp[], int maxwords, char sc);
|
|
||||||
int sanitizefile(char *buf);
|
|
||||||
int sanitizehost(char *buf);
|
|
||||||
void buildactualfile(struct connstruct *cn);
|
|
||||||
int issockwriteable(int sd);
|
|
||||||
int isdir(char *name);
|
|
||||||
int trycgi_withpathinfo(struct connstruct *cn);
|
|
||||||
|
|
||||||
// mime_types.c prototypes
|
// mime_types.c prototypes
|
||||||
void mime_init(void);
|
void mime_init(void);
|
||||||
const char *getmimetype(const char *fn);
|
const char *getmimetype(const char *fn);
|
||||||
|
|
||||||
// main.c prototypes
|
|
||||||
void initlists(void);
|
|
||||||
|
26
httpd/conn.c
26
httpd/conn.c
@ -27,9 +27,7 @@ void addconnection(int sd, char *ip, int is_ssl)
|
|||||||
|
|
||||||
// Get ourselves a connstruct
|
// Get ourselves a connstruct
|
||||||
if (freeconns == NULL)
|
if (freeconns == NULL)
|
||||||
{
|
tp = (struct connstruct *)malloc(sizeof(struct connstruct));
|
||||||
tp = (struct connstruct *) malloc(sizeof(struct connstruct));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tp = freeconns;
|
tp = freeconns;
|
||||||
@ -39,23 +37,21 @@ void addconnection(int sd, char *ip, int is_ssl)
|
|||||||
// Attach it to the used list
|
// Attach it to the used list
|
||||||
tp->next = usedconns;
|
tp->next = usedconns;
|
||||||
usedconns = tp;
|
usedconns = tp;
|
||||||
|
|
||||||
tp->networkdesc = sd;
|
tp->networkdesc = sd;
|
||||||
|
|
||||||
if (is_ssl)
|
if (is_ssl)
|
||||||
ssl_server_new(servers->ssl_ctx, sd);
|
ssl_server_new(servers->ssl_ctx, sd);
|
||||||
|
tp->is_ssl = is_ssl;
|
||||||
tp->filedesc = -1;
|
tp->filedesc = -1;
|
||||||
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
||||||
tp->dirp = NULL;
|
tp->dirp = NULL;
|
||||||
#endif
|
#endif
|
||||||
tp->is_ssl = is_ssl;
|
|
||||||
|
|
||||||
*(tp->actualfile) = '\0';
|
*(tp->actualfile) = '\0';
|
||||||
*(tp->filereq) = '\0';
|
*(tp->filereq) = '\0';
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
*(tp->cgiargs) = '\0';
|
*(tp->cgiargs) = '\0';
|
||||||
#endif
|
#endif
|
||||||
*(tp->virtualhostreq) = '\0';
|
*(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);
|
my_strncpy(tp->ip, ip, MAXIPLEN);
|
||||||
@ -67,27 +63,27 @@ void addconnection(int sd, char *ip, int is_ssl)
|
|||||||
void removeconnection(struct connstruct *cn)
|
void removeconnection(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
struct connstruct *tp;
|
struct connstruct *tp;
|
||||||
int shouldret=0;
|
int shouldret = 0;
|
||||||
|
|
||||||
tp = usedconns;
|
tp = usedconns;
|
||||||
|
|
||||||
if (tp == NULL || cn == NULL)
|
if (tp == NULL || cn == NULL)
|
||||||
shouldret=1;
|
shouldret = 1;
|
||||||
else if (tp == cn)
|
else if (tp == cn)
|
||||||
usedconns = tp->next;
|
usedconns = tp->next;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while(tp != NULL)
|
while (tp != NULL)
|
||||||
{
|
{
|
||||||
if (tp->next == cn)
|
if (tp->next == cn)
|
||||||
{
|
{
|
||||||
tp->next = (tp->next)->next;
|
tp->next = (tp->next)->next;
|
||||||
shouldret=0;
|
shouldret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp = tp->next;
|
tp = tp->next;
|
||||||
shouldret=1;
|
shouldret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,14 +98,14 @@ void removeconnection(struct connstruct *cn)
|
|||||||
if (cn->networkdesc != -1)
|
if (cn->networkdesc != -1)
|
||||||
{
|
{
|
||||||
if (cn->is_ssl)
|
if (cn->is_ssl)
|
||||||
{
|
|
||||||
ssl_free(ssl_find(servers->ssl_ctx, cn->networkdesc));
|
ssl_free(ssl_find(servers->ssl_ctx, cn->networkdesc));
|
||||||
}
|
|
||||||
|
|
||||||
SOCKET_CLOSE(cn->networkdesc);
|
SOCKET_CLOSE(cn->networkdesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cn->filedesc != -1) close(cn->filedesc);
|
if (cn->filedesc != -1)
|
||||||
|
close(cn->filedesc);
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
||||||
if (cn->dirp != NULL)
|
if (cn->dirp != NULL)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
523
httpd/main.c
523
httpd/main.c
@ -27,23 +27,25 @@
|
|||||||
struct serverstruct *servers;
|
struct serverstruct *servers;
|
||||||
struct connstruct *usedconns;
|
struct connstruct *usedconns;
|
||||||
struct connstruct *freeconns;
|
struct connstruct *freeconns;
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
|
||||||
struct cgiextstruct *cgiexts;
|
|
||||||
#endif
|
|
||||||
struct indexstruct *indexlist;
|
|
||||||
|
|
||||||
char *webroot = CONFIG_HTTP_WEBROOT;
|
char *webroot = CONFIG_HTTP_WEBROOT;
|
||||||
|
|
||||||
static void addindex(char *tp);
|
|
||||||
static void addtoservers(int sd);
|
static void addtoservers(int sd);
|
||||||
static void selectloop(void);
|
|
||||||
static int openlistener(int port);
|
static int openlistener(int port);
|
||||||
static void handlenewconnection(int listenfd, int is_ssl);
|
static void handlenewconnection(int listenfd, int is_ssl);
|
||||||
#if defined(CONFIG_HTTP_PERM_CHECK)
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
static void procpermcheck(char *pathtocheck);
|
static void procpermcheck(const char *pathtocheck);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
struct cgiextstruct *cgiexts;
|
||||||
static void addcgiext(char *tp);
|
static void addcgiext(char *tp);
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
static void reaper(int sigtype)
|
||||||
|
{
|
||||||
|
wait3(NULL, WNOHANG, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* clean up memory for valgrind */
|
/* clean up memory for valgrind */
|
||||||
@ -53,7 +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)
|
||||||
ssl_ctx_free(servers->ssl_ctx);
|
ssl_ctx_free(servers->ssl_ctx);
|
||||||
@ -63,9 +65,6 @@ static void sigint_cleanup(int sig)
|
|||||||
servers = sp;
|
servers = sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(indexlist->name);
|
|
||||||
free(indexlist);
|
|
||||||
|
|
||||||
for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++)
|
for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++)
|
||||||
{
|
{
|
||||||
if (freeconns == NULL)
|
if (freeconns == NULL)
|
||||||
@ -79,46 +78,52 @@ static void sigint_cleanup(int sig)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initlists()
|
static void die(int sigtype)
|
||||||
{
|
{
|
||||||
int i;
|
exit(0);
|
||||||
struct connstruct *tp;
|
|
||||||
|
|
||||||
servers = NULL;
|
|
||||||
usedconns = NULL;
|
|
||||||
freeconns = NULL;
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
|
||||||
cgiexts = NULL;
|
|
||||||
#endif
|
|
||||||
indexlist = NULL;
|
|
||||||
|
|
||||||
for (i=0; i<INITIAL_CONNECTION_SLOTS; i++)
|
|
||||||
{
|
|
||||||
tp = freeconns;
|
|
||||||
freeconns = (struct connstruct *) calloc(1, sizeof(struct connstruct));
|
|
||||||
freeconns->next = tp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int tp;
|
fd_set rfds, wfds;
|
||||||
#if defined(CONFIG_HTTP_IS_DAEMON)
|
struct connstruct *tp, *to;
|
||||||
int pid;
|
struct serverstruct *sp;
|
||||||
#endif
|
int rnum, wnum, active;
|
||||||
|
int webrootlen, i;
|
||||||
|
time_t currtime;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WORD wVersionRequested = MAKEWORD(2,2);
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(wVersionRequested,&wsaData);
|
WSAStartup(wVersionRequested,&wsaData);
|
||||||
|
#else
|
||||||
|
if (getuid() == 0) // change our uid if we are root
|
||||||
|
{
|
||||||
|
setgid(32767);
|
||||||
|
setuid(32767);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGQUIT, die);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
signal(SIGCHLD, reaper);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
signal(SIGINT, sigint_cleanup);
|
||||||
|
signal(SIGTERM, die);
|
||||||
mime_init();
|
mime_init();
|
||||||
initlists();
|
|
||||||
tp = strlen(webroot);
|
|
||||||
|
|
||||||
if (webroot[tp-1] == '/')
|
for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++)
|
||||||
webroot[tp-1] = '\0';
|
{
|
||||||
|
tp = freeconns;
|
||||||
|
freeconns = (struct connstruct *)calloc(1, sizeof(struct connstruct));
|
||||||
|
freeconns->next = tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
webrootlen = strlen(webroot);
|
||||||
|
|
||||||
|
if (webroot[webrootlen-1] == '/')
|
||||||
|
webroot[webrootlen-1] = '\0';
|
||||||
|
|
||||||
if (isdir(webroot) == 0)
|
if (isdir(webroot) == 0)
|
||||||
{
|
{
|
||||||
@ -128,38 +133,29 @@ int main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tp = openlistener(CONFIG_HTTP_PORT)) == -1)
|
if ((active = openlistener(CONFIG_HTTP_PORT)) == -1)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
fprintf(stderr, "ERR: Couldn't bind to port %d (IPv4)\n",
|
fprintf(stderr, "ERR: Couldn't bind to port %d\n",
|
||||||
CONFIG_HTTP_PORT);
|
CONFIG_HTTP_PORT);
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
addindex("index.html");
|
addtoservers(active);
|
||||||
addtoservers(tp);
|
|
||||||
|
|
||||||
#ifndef WIN32
|
if ((active = openlistener(CONFIG_HTTP_HTTPS_PORT)) == -1)
|
||||||
if (getuid() == 0)
|
|
||||||
{
|
|
||||||
setgid(32767);
|
|
||||||
setuid(32767);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((tp = openlistener(CONFIG_HTTP_HTTPS_PORT)) == -1)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
fprintf(stderr, "ERR: Couldn't bind to port %d (IPv4)\n",
|
fprintf(stderr, "ERR: Couldn't bind to port %d\n",
|
||||||
CONFIG_HTTP_HTTPS_PORT);
|
CONFIG_HTTP_HTTPS_PORT);
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
addtoservers(tp);
|
addtoservers(active);
|
||||||
servers->ssl_ctx = ssl_ctx_new(CONFIG_HTTP_DEFAULT_SSL_OPTIONS,
|
servers->ssl_ctx = ssl_ctx_new(CONFIG_HTTP_DEFAULT_SSL_OPTIONS,
|
||||||
CONFIG_HTTP_SESSION_CACHE_SIZE);
|
CONFIG_HTTP_SESSION_CACHE_SIZE);
|
||||||
servers->is_ssl = 1;
|
servers->is_ssl = 1;
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_PERM_CHECK)
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
@ -173,53 +169,152 @@ int main(int argc, char *argv[])
|
|||||||
CONFIG_HTTP_PORT, CONFIG_HTTP_HTTPS_PORT);
|
CONFIG_HTTP_PORT, CONFIG_HTTP_HTTPS_PORT);
|
||||||
TTY_FLUSH();
|
TTY_FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_IS_DAEMON)
|
#if defined(CONFIG_HTTP_IS_DAEMON)
|
||||||
pid = fork();
|
if (fork() > 0) /* parent will die */
|
||||||
|
|
||||||
if (pid > 0)
|
|
||||||
{
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
|
||||||
else if(pid == -1)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
|
||||||
fprintf(stderr,"axhttpd: Sorry, fork failed... Tough dice.\n");
|
|
||||||
#endif
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SIGNALS */
|
// main loop
|
||||||
signal(SIGINT, sigint_cleanup);
|
while (1)
|
||||||
signal(SIGTERM, die);
|
{
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
FD_ZERO(&rfds);
|
||||||
#ifndef WIN32
|
FD_ZERO(&wfds);
|
||||||
signal(SIGCHLD, reaper);
|
rnum = wnum = -1;
|
||||||
#endif
|
sp = servers;
|
||||||
#endif
|
|
||||||
#ifndef WIN32
|
while (sp != NULL) // read each server port
|
||||||
signal(SIGQUIT, die);
|
{
|
||||||
signal(SIGPIPE, SIG_IGN);
|
FD_SET(sp->sd, &rfds);
|
||||||
#endif
|
|
||||||
|
if (sp->sd > rnum)
|
||||||
|
rnum = sp->sd;
|
||||||
|
sp = sp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the established sockets
|
||||||
|
tp = usedconns;
|
||||||
|
currtime = time(NULL);
|
||||||
|
|
||||||
|
while (tp != NULL)
|
||||||
|
{
|
||||||
|
if (currtime > tp->timeout) // timed out? Kill it.
|
||||||
|
{
|
||||||
|
to = tp;
|
||||||
|
tp = tp->next;
|
||||||
|
removeconnection(to);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_READ_HEAD)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &rfds);
|
||||||
|
if (tp->networkdesc > rnum)
|
||||||
|
rnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_SEND_HEAD)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_READ_FILE)
|
||||||
|
{
|
||||||
|
FD_SET(tp->filedesc, &rfds);
|
||||||
|
if (tp->filedesc > rnum)
|
||||||
|
rnum = tp->filedesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_SEND_FILE)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
if (tp->state == STATE_DOING_DIR)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
active = select(wnum > rnum ? wnum+1 : rnum+1,
|
||||||
|
rnum != -1 ? &rfds : NULL, wnum != -1 ? &wfds : NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
// New connection?
|
||||||
|
sp = servers;
|
||||||
|
while (active > 0 && sp != NULL)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(sp->sd, &rfds))
|
||||||
|
{
|
||||||
|
handlenewconnection(sp->sd, sp->is_ssl);
|
||||||
|
active--;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = sp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the established sockets
|
||||||
|
tp = usedconns;
|
||||||
|
|
||||||
|
while (active > 0 && tp != NULL)
|
||||||
|
{
|
||||||
|
to = tp;
|
||||||
|
tp = tp->next;
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_READ_HEAD)
|
||||||
|
if (FD_ISSET(to->networkdesc, &rfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procreadhead(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_SEND_HEAD)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procsendhead(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_READ_FILE)
|
||||||
|
if (FD_ISSET(to->filedesc, &rfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procreadfile(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_SEND_FILE)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procsendfile(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
if (to->state == STATE_DOING_DIR)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procdodir(to);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selectloop();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addindex(char *tp)
|
|
||||||
{
|
|
||||||
struct indexstruct *ex = (struct indexstruct *)
|
|
||||||
malloc(sizeof(struct indexstruct));
|
|
||||||
ex->name = strdup(tp);
|
|
||||||
ex->next = indexlist;
|
|
||||||
indexlist = ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_PERM_CHECK)
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
static void procpermcheck(char *pathtocheck)
|
static void procpermcheck(const char *pathtocheck)
|
||||||
{
|
{
|
||||||
char thepath[MAXREQUESTLENGTH];
|
char thepath[MAXREQUESTLENGTH];
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -232,31 +327,35 @@ static void procpermcheck(char *pathtocheck)
|
|||||||
{
|
{
|
||||||
printf("WARNING: UID (%d) is unable to read %s\n",
|
printf("WARNING: UID (%d) is unable to read %s\n",
|
||||||
(int)getuid(), pathtocheck);
|
(int)getuid(), pathtocheck);
|
||||||
|
TTY_FLUSH();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((dp=readdir(tpdir)))
|
while ((dp = readdir(tpdir)))
|
||||||
{
|
{
|
||||||
if (strcmp(dp->d_name, "..")==0)
|
if (strcmp(dp->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp(dp->d_name, ".")==0)
|
if (strcmp(dp->d_name, ".") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(thepath, sizeof(thepath), "%s/%s", pathtocheck, dp->d_name);
|
snprintf(thepath, sizeof(thepath), "%s/%s", pathtocheck, dp->d_name);
|
||||||
|
|
||||||
if (isdir(thepath))
|
if (isdir(thepath))
|
||||||
{
|
{
|
||||||
procpermcheck(thepath);
|
procpermcheck(thepath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access(thepath, R_OK) != 0)
|
if (access(thepath, R_OK) != 0)
|
||||||
printf("WARNING: UID (%d) is unable to read %s\n",
|
printf("WARNING: UID (%d) is unable to read %s\n",
|
||||||
(int)getuid(), thepath);
|
(int)getuid(), thepath);
|
||||||
|
|
||||||
if (access(thepath, W_OK) == 0)
|
if (access(thepath, W_OK) == 0)
|
||||||
printf("SECURITY: UID (%d) is ABLE TO WRITE TO %s\n",
|
printf("SECURITY: UID (%d) is ABLE TO WRITE TO %s\n",
|
||||||
(int)getuid(), thepath);
|
(int)getuid(), thepath);
|
||||||
|
|
||||||
|
TTY_FLUSH();
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(tpdir);
|
closedir(tpdir);
|
||||||
@ -335,149 +434,6 @@ static void addtoservers(int sd)
|
|||||||
servers = tp;
|
servers = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void selectloop(void)
|
|
||||||
{
|
|
||||||
fd_set rfds, wfds;
|
|
||||||
struct connstruct *tp, *to;
|
|
||||||
struct serverstruct *sp;
|
|
||||||
int rnum, wnum, active;
|
|
||||||
int currtime;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
// MAIN SELECT LOOP
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
rnum = wnum = -1;
|
|
||||||
|
|
||||||
// Add the listening sockets
|
|
||||||
sp = servers;
|
|
||||||
while (sp != NULL)
|
|
||||||
{
|
|
||||||
FD_SET(sp->sd, &rfds);
|
|
||||||
if (sp->sd > rnum) rnum = sp->sd;
|
|
||||||
sp = sp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the established sockets
|
|
||||||
tp = usedconns;
|
|
||||||
currtime = time(NULL);
|
|
||||||
|
|
||||||
while (tp != NULL)
|
|
||||||
{
|
|
||||||
if (currtime > tp->timeout)
|
|
||||||
{
|
|
||||||
to = tp;
|
|
||||||
tp = tp->next;
|
|
||||||
removeconnection(to);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->state == STATE_WANT_TO_READ_HEAD)
|
|
||||||
{
|
|
||||||
FD_SET(tp->networkdesc, &rfds);
|
|
||||||
if (tp->networkdesc > rnum)
|
|
||||||
rnum = tp->networkdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->state == STATE_WANT_TO_SEND_HEAD)
|
|
||||||
{
|
|
||||||
FD_SET(tp->networkdesc, &wfds);
|
|
||||||
if (tp->networkdesc > wnum)
|
|
||||||
wnum = tp->networkdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->state == STATE_WANT_TO_READ_FILE)
|
|
||||||
{
|
|
||||||
FD_SET(tp->filedesc, &rfds);
|
|
||||||
if (tp->filedesc > rnum)
|
|
||||||
rnum = tp->filedesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->state == STATE_WANT_TO_SEND_FILE)
|
|
||||||
{
|
|
||||||
FD_SET(tp->networkdesc, &wfds);
|
|
||||||
if (tp->networkdesc > wnum)
|
|
||||||
wnum = tp->networkdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
|
||||||
if (tp->state == STATE_DOING_DIR)
|
|
||||||
{
|
|
||||||
FD_SET(tp->networkdesc, &wfds);
|
|
||||||
if (tp->networkdesc > wnum)
|
|
||||||
wnum = tp->networkdesc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
tp = tp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
active = select(wnum > rnum ? wnum+1 : rnum+1,
|
|
||||||
rnum != -1 ? &rfds : NULL,
|
|
||||||
wnum != -1 ? &wfds : NULL,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
// Handle the listening sockets
|
|
||||||
sp = servers;
|
|
||||||
while (active > 0 && sp != NULL)
|
|
||||||
{
|
|
||||||
if (FD_ISSET(sp->sd, &rfds))
|
|
||||||
{
|
|
||||||
handlenewconnection(sp->sd, sp->is_ssl);
|
|
||||||
active--;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = sp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the established sockets
|
|
||||||
tp = usedconns;
|
|
||||||
|
|
||||||
while (active > 0 && tp != NULL)
|
|
||||||
{
|
|
||||||
to = tp;
|
|
||||||
tp = tp->next;
|
|
||||||
|
|
||||||
if (to->state == STATE_WANT_TO_READ_HEAD)
|
|
||||||
if (FD_ISSET(to->networkdesc, &rfds))
|
|
||||||
{
|
|
||||||
active--;
|
|
||||||
procreadhead(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to->state == STATE_WANT_TO_SEND_HEAD)
|
|
||||||
if (FD_ISSET(to->networkdesc, &wfds))
|
|
||||||
{
|
|
||||||
active--;
|
|
||||||
procsendhead(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to->state == STATE_WANT_TO_READ_FILE)
|
|
||||||
if (FD_ISSET(to->filedesc, &rfds))
|
|
||||||
{
|
|
||||||
active--;
|
|
||||||
procreadfile(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to->state == STATE_WANT_TO_SEND_FILE)
|
|
||||||
if (FD_ISSET(to->networkdesc, &wfds))
|
|
||||||
{
|
|
||||||
active--;
|
|
||||||
procsendfile(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
|
||||||
if (to->state == STATE_DOING_DIR)
|
|
||||||
if (FD_ISSET(to->networkdesc, &wfds))
|
|
||||||
{
|
|
||||||
active--;
|
|
||||||
procdodir(to);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} // MAIN SELECT LOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
static void handlenewconnection(int listenfd, int is_ssl)
|
static void handlenewconnection(int listenfd, int is_ssl)
|
||||||
{
|
{
|
||||||
@ -486,9 +442,6 @@ static void handlenewconnection(int listenfd, int is_ssl)
|
|||||||
char ipbuf[100];
|
char ipbuf[100];
|
||||||
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
||||||
|
|
||||||
if (connfd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (tp == sizeof(struct sockaddr_in6))
|
if (tp == sizeof(struct sockaddr_in6))
|
||||||
{
|
{
|
||||||
inet_ntop(AF_INET6, &their_addr.sin6_addr, ipbuf, sizeof(ipbuf));
|
inet_ntop(AF_INET6, &their_addr.sin6_addr, ipbuf, sizeof(ipbuf));
|
||||||
@ -512,10 +465,6 @@ static void handlenewconnection(int listenfd, int is_ssl)
|
|||||||
struct sockaddr_in their_addr;
|
struct sockaddr_in their_addr;
|
||||||
int tp = sizeof(struct sockaddr_in);
|
int tp = sizeof(struct sockaddr_in);
|
||||||
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
||||||
|
|
||||||
if (connfd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
addconnection(connfd, inet_ntoa(their_addr.sin_addr), is_ssl);
|
addconnection(connfd, inet_ntoa(their_addr.sin_addr), is_ssl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -524,62 +473,60 @@ static int openlistener(int port)
|
|||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
char tp=1;
|
char tp = 1;
|
||||||
#else
|
#else
|
||||||
int tp=1;
|
int tp = 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_IPV6
|
||||||
struct sockaddr_in my_addr;
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp));
|
memset(&my_addr, 0, sizeof(my_addr));
|
||||||
my_addr.sin_family = AF_INET; // host byte order
|
my_addr.sin_family = AF_INET;
|
||||||
my_addr.sin_port = htons((short)port); // short, network byte order
|
my_addr.sin_port = htons((short)port);
|
||||||
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
|
my_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
memset(&(my_addr.sin_zero), 0, 8); // zero the rest of the struct
|
#else
|
||||||
|
|
||||||
if (bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
|
|
||||||
{
|
|
||||||
close(sd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen(sd, BACKLOG) == -1)
|
|
||||||
{
|
|
||||||
close(sd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
static int openlistener6(int port)
|
|
||||||
{
|
|
||||||
int sd,tp;
|
|
||||||
struct sockaddr_in6 my_addr;
|
struct sockaddr_in6 my_addr;
|
||||||
|
|
||||||
if ((sd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
|
if ((sd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp));
|
|
||||||
memset(&my_addr, 0, sizeof(my_addr));
|
memset(&my_addr, 0, sizeof(my_addr));
|
||||||
my_addr.sin6_family = AF_INET6;
|
my_addr.sin6_family = AF_INET6;
|
||||||
my_addr.sin6_port = htons(port);
|
my_addr.sin6_port = htons(port);
|
||||||
|
my_addr.sin6_addr.s_addr = INADDR_ANY;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bind(sd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
|
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp));
|
||||||
{
|
bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
|
||||||
close(sd);
|
listen(sd, BACKLOG);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen(sd, BACKLOG) == -1)
|
|
||||||
{
|
|
||||||
close(sd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/* Wrapper function for strncpy() that guarantees
|
||||||
|
a null-terminated string. This is to avoid any possible
|
||||||
|
issues due to strncpy()'s behaviour.
|
||||||
|
*/
|
||||||
|
char *my_strncpy(char *dest, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
strncpy(dest, src, n);
|
||||||
|
dest[n-1] = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isdir(const char *tpbuf)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(tpbuf, &st) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((st.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
441
httpd/proc.c
441
httpd/proc.c
@ -27,21 +27,31 @@
|
|||||||
#include "axhttp.h"
|
#include "axhttp.h"
|
||||||
|
|
||||||
static int special_read(struct connstruct *cn, void *buf, size_t count);
|
static int special_read(struct connstruct *cn, void *buf, size_t count);
|
||||||
|
static int special_write(struct connstruct *cn,
|
||||||
|
const uint8_t *buf, size_t count);
|
||||||
static void send301(struct connstruct *cn);
|
static void send301(struct connstruct *cn);
|
||||||
static void send404(struct connstruct *cn);
|
static void send404(struct connstruct *cn);
|
||||||
static int procindex(struct connstruct *cn, struct stat *stp);
|
static int procindex(struct connstruct *cn, struct stat *stp);
|
||||||
static int hexit(char c);
|
static int hexit(char c);
|
||||||
static void urldecode(char *buf);
|
static void urldecode(char *buf);
|
||||||
|
static void buildactualfile(struct connstruct *cn);
|
||||||
|
static int sanitizefile(const char *buf);
|
||||||
|
static int sanitizehost(char *buf);
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
static void urlencode(unsigned char *s, unsigned char *t);
|
static void urlencode(const uint8_t *s, uint8_t *t);
|
||||||
|
static void procdirlisting(struct connstruct *cn);
|
||||||
|
static int issockwriteable(int sd);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
static void proccgi(struct connstruct *cn, int has_pathinfo);
|
static void proccgi(struct connstruct *cn, int has_pathinfo);
|
||||||
|
static int trycgi_withpathinfo(struct connstruct *cn);
|
||||||
|
static void split(char *tp, char *sp[], int maxwords, char sc);
|
||||||
|
static int iscgi(const char *fn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Returns 1 if elems should continue being read, 0 otherwise
|
// Returns 1 if elems should continue being read, 0 otherwise
|
||||||
int procheadelem(struct connstruct *cn, char *buf)
|
static int procheadelem(struct connstruct *cn, char *buf)
|
||||||
{
|
{
|
||||||
char *delim, *value;
|
char *delim, *value;
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
@ -98,7 +108,8 @@ int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
my_strncpy(cn->virtualhostreq, value, MAXREQUESTLENGTH);
|
my_strncpy(cn->virtualhostreq, value, MAXREQUESTLENGTH);
|
||||||
}
|
}
|
||||||
else if (strcmp(buf, "Connection:")==0 &&
|
else if (strcmp(buf, "Connection:")==0 &&
|
||||||
strcmp(value, "close")==0) {
|
strcmp(value, "close")==0)
|
||||||
|
{
|
||||||
cn->close_when_done = 1;
|
cn->close_when_done = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(buf, "If-Modified-Since:") ==0 )
|
else if (strcmp(buf, "If-Modified-Since:") ==0 )
|
||||||
@ -111,33 +122,26 @@ int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
void procdirlisting(struct connstruct *cn)
|
static void procdirlisting(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char buf[MAXREQUESTLENGTH];
|
char buf[MAXREQUESTLENGTH];
|
||||||
char actualfile[1024];
|
char actualfile[1024];
|
||||||
|
|
||||||
#ifndef CONFIG_HTTP_DIRECTORIES
|
|
||||||
if (allowdirectorylisting == 0)
|
|
||||||
{
|
|
||||||
send404(cn);
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cn->reqtype == TYPE_HEAD)
|
if (cn->reqtype == TYPE_HEAD)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nContent-Type: text/html\n\n");
|
snprintf(buf, sizeof(buf),
|
||||||
|
"HTTP/1.1 200 OK\nContent-Type: text/html\n\n");
|
||||||
write(cn->networkdesc, buf, strlen(buf));
|
write(cn->networkdesc, buf, strlen(buf));
|
||||||
|
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(actualfile, cn->actualfile);
|
strcpy(actualfile, cn->actualfile);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
strcat(actualfile, "*");
|
strcat(actualfile, "*");
|
||||||
cn->dirp = FindFirstFile(actualfile, &cn->file_data);
|
cn->dirp = FindFirstFile(actualfile, &cn->file_data);
|
||||||
|
|
||||||
if (cn->dirp == INVALID_HANDLE_VALUE)
|
if (cn->dirp == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
send404(cn);
|
send404(cn);
|
||||||
@ -145,10 +149,7 @@ void procdirlisting(struct connstruct *cn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
if ((cn->dirp = opendir(actualfile)) == NULL)
|
||||||
cn->dirp = opendir(actualfile);
|
|
||||||
|
|
||||||
if (cn->dirp == NULL)
|
|
||||||
{
|
{
|
||||||
send404(cn);
|
send404(cn);
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
@ -159,7 +160,10 @@ void procdirlisting(struct connstruct *cn)
|
|||||||
readdir(cn->dirp);
|
readdir(cn->dirp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sprintf(buf, "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<HTML><BODY>\n<TITLE>Directory Listing</TITLE>\n<H2>Directory listing of %s://%s%s</H2><BR>\n", cn->is_ssl ? "https" : "http", cn->virtualhostreq, cn->filereq);
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nContent-Type: text/html\n\n"
|
||||||
|
"<HTML><BODY>\n<TITLE>Directory Listing</TITLE>\n"
|
||||||
|
"<H2>Directory listing of %s://%s%s</H2><BR>\n",
|
||||||
|
cn->is_ssl ? "https" : "http", cn->virtualhostreq, cn->filereq);
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
cn->state = STATE_DOING_DIR;
|
cn->state = STATE_DOING_DIR;
|
||||||
}
|
}
|
||||||
@ -179,14 +183,14 @@ void procdodir(struct connstruct *cn)
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (!FindNextFile(cn->dirp, &cn->file_data))
|
if (!FindNextFile(cn->dirp, &cn->file_data))
|
||||||
#else
|
#else
|
||||||
if ((dp = readdir(cn->dirp)) == NULL)
|
if ((dp = readdir(cn->dirp)) == NULL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "</BODY></HTML>\n");
|
snprintf(buf, sizeof(buf), "</BODY></HTML>\n");
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
file = cn->file_data.cFileName;
|
file = cn->file_data.cFileName;
|
||||||
@ -199,31 +203,45 @@ void procdodir(struct connstruct *cn)
|
|||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file);
|
snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file);
|
||||||
putslash = isdir(buf);
|
putslash = isdir(buf);
|
||||||
|
|
||||||
urlencode(file, encbuf);
|
urlencode(file, encbuf);
|
||||||
snprintf(buf, sizeof(buf), "<A HREF=\"%s%s\">%s%s</A><BR>\n",
|
snprintf(buf, sizeof(buf), "<A HREF=\"%s%s\">%s%s</A><BR>\n",
|
||||||
encbuf, putslash ? "/" : "", file, putslash ? "/" : "");
|
encbuf, putslash ? "/" : "", file, putslash ? "/" : "");
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
|
} while (issockwriteable(cn->networkdesc));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
static int issockwriteable(int sd)
|
||||||
while (issockwriteable(cn->networkdesc));
|
{
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(sd, &wfds);
|
||||||
|
|
||||||
|
select(FD_SETSIZE, NULL, &wfds, NULL, &tv);
|
||||||
|
return FD_ISSET(sd, &wfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode funny chars -> %xx in newly allocated storage */
|
/* Encode funny chars -> %xx in newly allocated storage */
|
||||||
/* (preserves '/' !) */
|
/* (preserves '/' !) */
|
||||||
static void urlencode(unsigned char *s, unsigned char *t)
|
static void urlencode(const uint8_t *s, uint8_t *t)
|
||||||
{
|
{
|
||||||
uint8_t *p, *tp;
|
const uint8_t *p = s;
|
||||||
|
uint8_t *tp;
|
||||||
|
|
||||||
tp =t ;
|
tp = t;
|
||||||
|
|
||||||
for (p=s; *p; p++)
|
for (; *p; p++)
|
||||||
{
|
{
|
||||||
if ((*p > 0x00 && *p < ',') ||
|
if ((*p > 0x00 && *p < ',') ||
|
||||||
(*p > '9' && *p < 'A') ||
|
(*p > '9' && *p < 'A') ||
|
||||||
(*p > 'Z' && *p < '_') ||
|
(*p > 'Z' && *p < '_') ||
|
||||||
(*p > '_' && *p < 'a') ||
|
(*p > '_' && *p < 'a') ||
|
||||||
(*p > 'z' && *p < 0xA1)) {
|
(*p > 'z' && *p < 0xA1))
|
||||||
|
{
|
||||||
sprintf((char *)tp, "%%%02X", *p);
|
sprintf((char *)tp, "%%%02X", *p);
|
||||||
tp += 3;
|
tp += 3;
|
||||||
}
|
}
|
||||||
@ -245,24 +263,23 @@ void procreadhead(struct connstruct *cn)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = special_read(cn, buf, sizeof(buf)-1);
|
rv = special_read(cn, buf, sizeof(buf)-1);
|
||||||
if (rv <= 0) {
|
if (rv <= 0)
|
||||||
if (rv < 0)
|
{
|
||||||
|
if (rv < 0) // really dead?
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[rv] = '\0';
|
buf[rv] = '\0';
|
||||||
|
|
||||||
next = tp = buf;
|
next = tp = buf;
|
||||||
|
|
||||||
// Split up lines and send to procheadelem()
|
// Split up lines and send to procheadelem()
|
||||||
while(*next != '\0')
|
while (*next != '\0')
|
||||||
{
|
{
|
||||||
// If we have a blank line, advance to next stage!
|
// If we have a blank line, advance to next stage!
|
||||||
if (*next == '\r' || *next == '\n')
|
if (*next == '\r' || *next == '\n')
|
||||||
{
|
{
|
||||||
buildactualfile(cn);
|
buildactualfile(cn);
|
||||||
|
|
||||||
cn->state = STATE_WANT_TO_SEND_HEAD;
|
cn->state = STATE_WANT_TO_SEND_HEAD;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -273,7 +290,7 @@ void procreadhead(struct connstruct *cn)
|
|||||||
if (*next == '\r')
|
if (*next == '\r')
|
||||||
{
|
{
|
||||||
*next = '\0';
|
*next = '\0';
|
||||||
next+=2;
|
next += 2;
|
||||||
}
|
}
|
||||||
else if (*next == '\n')
|
else if (*next == '\n')
|
||||||
*next++ = '\0';
|
*next++ = '\0';
|
||||||
@ -295,8 +312,8 @@ void procsendhead(struct connstruct *cn)
|
|||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
||||||
char date[32];
|
char date[32];
|
||||||
strcpy(date, ctime(&now));
|
|
||||||
|
|
||||||
|
strcpy(date, ctime(&now));
|
||||||
strcpy(actualfile, cn->actualfile);
|
strcpy(actualfile, cn->actualfile);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -309,8 +326,9 @@ void procsendhead(struct connstruct *cn)
|
|||||||
{
|
{
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
if (trycgi_withpathinfo(cn) == 0)
|
if (trycgi_withpathinfo(cn) == 0)
|
||||||
{ // We Try To Find A CGI
|
{
|
||||||
proccgi(cn,1);
|
// We Try To Find A CGI
|
||||||
|
proccgi(cn, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -321,7 +339,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#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
|
// Set up CGI script
|
||||||
@ -333,7 +351,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proccgi(cn,0);
|
proccgi(cn, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -362,7 +380,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
// If the index is a CGI file, handle it like any other CGI
|
// If the index is a CGI file, handle it like any other CGI
|
||||||
if (iscgi(cn->actualfile))
|
if (iscgi(cn->actualfile))
|
||||||
{
|
{
|
||||||
// Set up CGI script
|
// Set up CGI script
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
@ -372,45 +390,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proccgi(cn,0);
|
proccgi(cn, 0);
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// If the index isn't a CGI, we continue on with the index file
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
|
|
||||||
{
|
|
||||||
if (cn->filereq[strlen(cn->filereq)-1] != '/')
|
|
||||||
{
|
|
||||||
send301(cn);
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if this dir has an index file
|
|
||||||
if (procindex(cn, &stbuf) == 0)
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_HTTP_DIRECTORIES)
|
|
||||||
// If not, we do a directory listing of it
|
|
||||||
procdirlisting(cn);
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
|
||||||
// If the index is a CGI file, handle it like any other CGI
|
|
||||||
if (iscgi(cn->actualfile))
|
|
||||||
{
|
|
||||||
// Set up CGI script
|
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
|
||||||
{
|
|
||||||
send404(cn);
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
proccgi(cn,0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -419,7 +399,8 @@ void procsendhead(struct connstruct *cn)
|
|||||||
|
|
||||||
if (cn->modified_since)
|
if (cn->modified_since)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 304 Not Modified\nServer: axhttpd V%s\nDate: %s\n", VERSION, date);
|
snprintf(buf, sizeof(buf), "HTTP/1.1 304 Not Modified\nServer: "
|
||||||
|
"axhttpd V%s\nDate: %s\n", VERSION, date);
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
cn->modified_since = 0;
|
cn->modified_since = 0;
|
||||||
cn->state = STATE_WANT_TO_READ_HEAD;
|
cn->state = STATE_WANT_TO_READ_HEAD;
|
||||||
@ -433,12 +414,11 @@ void procsendhead(struct connstruct *cn)
|
|||||||
TTY_FLUSH();
|
TTY_FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\nContent-Type: %s\nContent-Length: %ld\nDate: %sLast-Modified: %s\n",
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n"
|
||||||
VERSION,
|
"Content-Type: %s\nContent-Length: %ld\n"
|
||||||
getmimetype(cn->actualfile),
|
"Date: %sLast-Modified: %s\n", VERSION,
|
||||||
(long) stbuf.st_size,
|
getmimetype(cn->actualfile), (long) stbuf.st_size,
|
||||||
date,
|
date, ctime(&(stbuf.st_mtime))); // ctime() has a \n on the end
|
||||||
ctime(&(stbuf.st_mtime))); // ctime() has a \n on the end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
@ -478,7 +458,6 @@ void procsendhead(struct connstruct *cn)
|
|||||||
#else
|
#else
|
||||||
cn->state = STATE_WANT_TO_READ_FILE;
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
#endif
|
#endif
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,10 +469,11 @@ void procreadfile(struct connstruct *cn)
|
|||||||
{
|
{
|
||||||
close(cn->filedesc);
|
close(cn->filedesc);
|
||||||
cn->filedesc = -1;
|
cn->filedesc = -1;
|
||||||
if (cn->close_when_done) /* close immediately */
|
|
||||||
|
if (cn->close_when_done) /* close immediately */
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
else
|
else
|
||||||
{ /* keep socket open - HTTP 1.1 */
|
{ /* keep socket open - HTTP 1.1 */
|
||||||
cn->state = STATE_WANT_TO_READ_HEAD;
|
cn->state = STATE_WANT_TO_READ_HEAD;
|
||||||
cn->numbytes = 0;
|
cn->numbytes = 0;
|
||||||
}
|
}
|
||||||
@ -514,7 +494,9 @@ void procsendfile(struct connstruct *cn)
|
|||||||
else if (rv == cn->numbytes)
|
else if (rv == cn->numbytes)
|
||||||
cn->state = STATE_WANT_TO_READ_FILE;
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
else if (rv == 0)
|
else if (rv == 0)
|
||||||
{ /* Do nothing */ }
|
{
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memmove(cn->databuf, cn->databuf + rv, cn->numbytes - rv);
|
memmove(cn->databuf, cn->databuf + rv, cn->numbytes - rv);
|
||||||
@ -522,24 +504,16 @@ void procsendfile(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int special_write(struct connstruct *cn, const uint8_t *buf, size_t count)
|
static int special_write(struct connstruct *cn,
|
||||||
|
const uint8_t *buf, size_t count)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
|
|
||||||
if (cn->is_ssl)
|
if (cn->is_ssl)
|
||||||
{
|
{
|
||||||
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
||||||
if (ssl)
|
return ssl ? ssl_write(ssl, (uint8_t *)buf, count) : -1;
|
||||||
{
|
|
||||||
res = ssl_write(ssl, (unsigned char *)buf, count);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = SOCKET_WRITE(cn->networkdesc, buf, count);
|
return SOCKET_WRITE(cn->networkdesc, buf, count);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int special_read(struct connstruct *cn, void *buf, size_t count)
|
static int special_read(struct connstruct *cn, void *buf, size_t count)
|
||||||
@ -549,7 +523,7 @@ static int special_read(struct connstruct *cn, void *buf, size_t count)
|
|||||||
if (cn->is_ssl)
|
if (cn->is_ssl)
|
||||||
{
|
{
|
||||||
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
||||||
unsigned char *read_buf;
|
uint8_t *read_buf;
|
||||||
|
|
||||||
if ((res = ssl_read(ssl, &read_buf)) > SSL_OK)
|
if ((res = ssl_read(ssl, &read_buf)) > SSL_OK)
|
||||||
memcpy(buf, read_buf, res > (int)count ? count : res);
|
memcpy(buf, read_buf, res > (int)count ? count : res);
|
||||||
@ -566,26 +540,12 @@ static int special_read(struct connstruct *cn, void *buf, size_t count)
|
|||||||
static int procindex(struct connstruct *cn, struct stat *stp)
|
static int procindex(struct connstruct *cn, struct stat *stp)
|
||||||
{
|
{
|
||||||
char tbuf[MAXREQUESTLENGTH];
|
char tbuf[MAXREQUESTLENGTH];
|
||||||
struct indexstruct *tp;
|
|
||||||
|
|
||||||
tp = indexlist;
|
sprintf(tbuf, "%s%s", cn->actualfile, "index.html");
|
||||||
|
if (stat(tbuf, stp) != -1)
|
||||||
while(tp != NULL) {
|
{
|
||||||
sprintf(tbuf, "%s%s%s", cn->actualfile,
|
my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH);
|
||||||
#ifdef WIN32
|
return 1;
|
||||||
"\\",
|
|
||||||
#else
|
|
||||||
"/",
|
|
||||||
#endif
|
|
||||||
tp->name);
|
|
||||||
|
|
||||||
if (stat(tbuf, stp) != -1)
|
|
||||||
{
|
|
||||||
my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp = tp->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -599,8 +559,6 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
char buf[MAXREQUESTLENGTH];
|
char buf[MAXREQUESTLENGTH];
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int tmp_stdout;
|
int tmp_stdout;
|
||||||
#else
|
|
||||||
int fv;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n%s",
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n%s",
|
||||||
@ -614,28 +572,15 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (pipe(tpipe) == -1)
|
pipe(tpipe);
|
||||||
{
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fv = fork();
|
if (fork() > 0) // parent
|
||||||
|
|
||||||
if (fv == -1)
|
|
||||||
{
|
|
||||||
close(tpipe[0]);
|
|
||||||
close(tpipe[1]);
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fv != 0)
|
|
||||||
{
|
{
|
||||||
// Close the write descriptor
|
// Close the write descriptor
|
||||||
close(tpipe[1]);
|
close(tpipe[1]);
|
||||||
cn->filedesc = tpipe[0];
|
cn->filedesc = tpipe[0];
|
||||||
cn->state = STATE_WANT_TO_READ_FILE;
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
cn->close_when_done = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +598,6 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
|
|
||||||
close(tpipe[0]);
|
close(tpipe[0]);
|
||||||
close(tpipe[1]);
|
close(tpipe[1]);
|
||||||
|
|
||||||
myargs[0] = cn->actualfile;
|
myargs[0] = cn->actualfile;
|
||||||
myargs[1] = cn->cgiargs;
|
myargs[1] = cn->cgiargs;
|
||||||
myargs[2] = NULL;
|
myargs[2] = NULL;
|
||||||
@ -666,11 +610,7 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
|
|
||||||
execv(cn->actualfile, myargs);
|
execv(cn->actualfile, myargs);
|
||||||
#else /* WIN32 */
|
#else /* WIN32 */
|
||||||
if (_pipe(tpipe, 4096, O_BINARY| O_NOINHERIT) == -1)
|
_pipe(tpipe, 4096, O_BINARY| O_NOINHERIT);
|
||||||
{
|
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
myargs[0] = "sh";
|
myargs[0] = "sh";
|
||||||
myargs[1] = "-c";
|
myargs[1] = "-c";
|
||||||
@ -703,6 +643,7 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
close(tmp_stdout);
|
close(tmp_stdout);
|
||||||
cn->filedesc = tpipe[0];
|
cn->filedesc = tpipe[0];
|
||||||
cn->state = STATE_WANT_TO_READ_FILE;
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
cn->close_when_done = 1;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -716,6 +657,97 @@ static void proccgi(struct connstruct *cn, int has_pathinfo)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int trycgi_withpathinfo(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char tpfile[MAXREQUESTLENGTH];
|
||||||
|
char fr_str[MAXREQUESTLENGTH];
|
||||||
|
char *fr_rs[MAXCGIARGS]; // filereq splitted
|
||||||
|
int i = 0, offset;
|
||||||
|
|
||||||
|
my_strncpy(fr_str, cn->filereq, MAXREQUESTLENGTH);
|
||||||
|
split(fr_str, fr_rs, MAXCGIARGS, '/');
|
||||||
|
|
||||||
|
while (fr_rs[i] != NULL)
|
||||||
|
{
|
||||||
|
snprintf(tpfile, sizeof(tpfile), "%s/%s%s",
|
||||||
|
webroot, cn->virtualhostreq, fr_str);
|
||||||
|
|
||||||
|
if (iscgi(tpfile) && isdir(tpfile) == 0)
|
||||||
|
{
|
||||||
|
/* We've found our CGI file! */
|
||||||
|
my_strncpy(cn->actualfile, tpfile, MAXREQUESTLENGTH);
|
||||||
|
my_strncpy(cn->cgiscriptinfo, fr_str, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
|
offset = (fr_rs[i] + strlen(fr_rs[i])) - fr_str;
|
||||||
|
my_strncpy(cn->cgipathinfo, cn->filereq+offset, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(fr_rs[i]+strlen(fr_rs[i])) = '/';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Couldn't find any CGIs :( */
|
||||||
|
*(cn->cgiscriptinfo) = '\0';
|
||||||
|
*(cn->cgipathinfo) = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iscgi(const char *fn)
|
||||||
|
{
|
||||||
|
struct cgiextstruct *tp;
|
||||||
|
int fnlen, extlen;
|
||||||
|
|
||||||
|
fnlen = strlen(fn);
|
||||||
|
tp = cgiexts;
|
||||||
|
|
||||||
|
while (tp != NULL)
|
||||||
|
{
|
||||||
|
extlen = strlen(tp->ext);
|
||||||
|
|
||||||
|
if (strcasecmp(fn+(fnlen-extlen), tp->ext) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void split(char *tp, char *sp[], int maxwords, char sc)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
/* Skip leading whitespace */
|
||||||
|
while (*tp == sc) tp++;
|
||||||
|
|
||||||
|
if (*tp == '\0')
|
||||||
|
{
|
||||||
|
sp[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==maxwords-2)
|
||||||
|
{
|
||||||
|
sp[maxwords-2] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp[i] = tp;
|
||||||
|
|
||||||
|
while(*tp != sc && *tp != '\0')
|
||||||
|
tp++;
|
||||||
|
|
||||||
|
if (*tp == sc)
|
||||||
|
*tp++ = '\0';
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* CONFIG_HTTP_HAS_CGI */
|
#endif /* CONFIG_HTTP_HAS_CGI */
|
||||||
|
|
||||||
/* Decode string %xx -> char (in place) */
|
/* Decode string %xx -> char (in place) */
|
||||||
@ -730,26 +762,28 @@ static void urldecode(char *buf)
|
|||||||
{
|
{
|
||||||
v = 0;
|
v = 0;
|
||||||
|
|
||||||
if (*p=='%')
|
if (*p == '%')
|
||||||
{
|
{
|
||||||
s = p;
|
s = p;
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
if (isxdigit((int) s[0]) && isxdigit((int) s[1]))
|
if (isxdigit((int) s[0]) && isxdigit((int) s[1]))
|
||||||
{
|
{
|
||||||
v = hexit(s[0])*16+hexit(s[1]);
|
v = hexit(s[0])*16 + hexit(s[1]);
|
||||||
|
|
||||||
if (v)
|
if (v)
|
||||||
{ /* do not decode %00 to null char */
|
{
|
||||||
*w=(char)v;
|
/* do not decode %00 to null char */
|
||||||
p=&s[1];
|
*w = (char)v;
|
||||||
|
p = &s[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v)
|
if (!v) *w=*p;
|
||||||
*w=*p;
|
p++;
|
||||||
p++; w++;
|
w++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*w='\0';
|
*w='\0';
|
||||||
@ -757,27 +791,98 @@ static void urldecode(char *buf)
|
|||||||
|
|
||||||
static int hexit(char c)
|
static int hexit(char c)
|
||||||
{
|
{
|
||||||
if ( c >= '0' && c <= '9' )
|
if (c >= '0' && c <= '9')
|
||||||
return c - '0';
|
return c - '0';
|
||||||
if ( c >= 'a' && c <= 'f' )
|
else if (c >= 'a' && c <= 'f')
|
||||||
return c - 'a' + 10;
|
return c - 'a' + 10;
|
||||||
if ( c >= 'A' && c <= 'F' )
|
else if (c >= 'A' && c <= 'F')
|
||||||
return c - 'A' + 10;
|
return c - 'A' + 10;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send301(struct connstruct *cn)
|
static void send301(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
snprintf(buf, sizeof(buf), "HTTP/1.1 301 Moved Permanently\nLocation: %s/\n\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<HTML><HEAD>\n<TITLE>301 Moved Permanently</TITLE>\n</HEAD><BODY>\n<H1>Moved Permanently</H1>\nThe document has moved <A HREF=\"%s/\">here</A>.<P>\n<HR>\n</BODY></HTML>\n", cn->filereq, cn->filereq);
|
snprintf(buf, sizeof(buf),
|
||||||
|
"HTTP/1.1 301 Moved Permanently\nLocation: %s/\n\n"
|
||||||
|
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
|
||||||
|
"<HTML><HEAD>\n<TITLE>301 Moved Permanently</TITLE>\n"
|
||||||
|
"</HEAD><BODY>\n<H1>Moved Permanently</H1>\n"
|
||||||
|
"The document has moved <A HREF=\"%s/\">here</A>.<P>\n"
|
||||||
|
"<HR>\n</BODY></HTML>\n", cn->filereq, cn->filereq);
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send404(struct connstruct *cn)
|
static void send404(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
sprintf(buf, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\n<HTML><BODY>\n<TITLE>404 Not Found</TITLE><H1>It ain't there my friend. (404 Not Found)</H1>\n</BODY></HTML>\n");
|
strcpy(buf, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\n"
|
||||||
|
"<HTML><BODY>\n<TITLE>404 Not Found</TITLE><H1>"
|
||||||
|
"404 Not Found</H1>\n</BODY></HTML>\n");
|
||||||
special_write(cn, buf, strlen(buf));
|
special_write(cn, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void buildactualfile(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s%s", webroot, cn->filereq);
|
||||||
|
|
||||||
|
/* Add directory slash if not there */
|
||||||
|
if (isdir(cn->actualfile) &&
|
||||||
|
cn->actualfile[strlen(cn->actualfile)-1] != '/')
|
||||||
|
strcat(cn->actualfile, "/");
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* convert all the forward slashes to back slashes */
|
||||||
|
{
|
||||||
|
char *t = cn->actualfile;
|
||||||
|
while ((t = strchr(t, '/')))
|
||||||
|
{
|
||||||
|
*t++ = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sanitizefile(const char *buf)
|
||||||
|
{
|
||||||
|
int len, i;
|
||||||
|
|
||||||
|
// Don't accept anything not starting with a /
|
||||||
|
if (*buf != '/')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len = strlen(buf);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
// Check for "/." : In other words, don't send files starting with a .
|
||||||
|
// Notice, GOBBLES, that this includes ".."
|
||||||
|
if (buf[i] == '/' && buf[i+1] == '.')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sanitizehost(char *buf)
|
||||||
|
{
|
||||||
|
while (*buf != '\0')
|
||||||
|
{
|
||||||
|
// Handle the port
|
||||||
|
if (*buf == ':')
|
||||||
|
{
|
||||||
|
*buf = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce some basic URL rules...
|
||||||
|
if (isalnum(*buf)==0 && *buf != '-' && *buf != '.') return 0;
|
||||||
|
if (*buf == '.' && *(buf+1) == '.') return 0;
|
||||||
|
if (*buf == '.' && *(buf+1) == '-') return 0;
|
||||||
|
if (*buf == '-' && *(buf+1) == '.') return 0;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
352
www/index.html
352
www/index.html
@ -1,7 +1,7 @@
|
|||||||
<html><head><title>An Overview of Cryptography</title>
|
<html><head><title>An Overview of Cryptography</title>
|
||||||
|
|
||||||
|
|
||||||
<meta name="keywords" content="crypto tutorial, cryptography tutorial, DES tutorial, RSA tutorial, Diffie-Hellman tutorial, IPsec tutorial, PGP tutorial, SSL tutorial, ECC tutorial, elliptic curve cryptography tutorial, AES tutorial, Rijndael tutorial"></head><body bgcolor="#ffffff">
|
<meta name="keywords" content="crypto tutorial, cryptography tutorial, DES tutorial, RSA tutorial, Diffie-Hellman tutorial, IPsec tutorial, PGP tutorial, SSL tutorial, ECC tutorial, elliptic curve cryptography tutorial, AES tutorial, Rijndael tutorial, secret key cryptography, public key cryptography, hash functions"></head><body bgcolor="#ffffff">
|
||||||
<font size="3">
|
<font size="3">
|
||||||
</font><center>
|
</font><center>
|
||||||
<h1>
|
<h1>
|
||||||
@ -12,7 +12,7 @@ An Overview of Cryptography
|
|||||||
<h3>
|
<h3>
|
||||||
<font size="3"><i><a href="mailto:kumquat@sover.net">Gary C. Kessler</a></i><br>
|
<font size="3"><i><a href="mailto:kumquat@sover.net">Gary C. Kessler</a></i><br>
|
||||||
May 1998<br>
|
May 1998<br>
|
||||||
(26 September 2005)
|
(1 August 2006)
|
||||||
</font></h3>
|
</font></h3>
|
||||||
<font size="3"><br>
|
<font size="3"><br>
|
||||||
</font><blockquote>
|
</font><blockquote>
|
||||||
@ -193,7 +193,7 @@ algorithms that will be discussed are (Figure 1):
|
|||||||
</li></font></ul>
|
</li></font></ul>
|
||||||
<font size="3"><a name="fig01"></a><br>
|
<font size="3"><a name="fig01"></a><br>
|
||||||
</font><center><table border="1"><tbody><tr><td>
|
</font><center><table border="1"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_types.gif">
|
<img src="index_files/crypto_types.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 1: Three types of cryptography: secret-key, public key, and hash function.</h4>
|
<h4>FIGURE 1: Three types of cryptography: secret-key, public key, and hash function.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -366,7 +366,7 @@ Telegraph and Telephone (NTT) Corp. and Mitsubishi Electric Corporation
|
|||||||
and suitability for both software and hardware implementations on
|
and suitability for both software and hardware implementations on
|
||||||
common 32-bit processors as well as 8-bit processors (e.g., smart
|
common 32-bit processors as well as 8-bit processors (e.g., smart
|
||||||
cards, cryptographic hardware, and embedded systems). Also described in
|
cards, cryptographic hardware, and embedded systems). Also described in
|
||||||
<a href="http://www.rfc-editor.org/rfc/rfc3713.txt"> RFC 3713</a>.</p></li>
|
<a href="http://www.rfc-editor.org/rfc/rfc3713.txt"> RFC 3713</a>. Camellia's application in IPsec is described in <a href="http://www.rfc-editor.org/rfc/rfc4312.txt"> RFC 4312</a>.</p></li>
|
||||||
|
|
||||||
<li> <p><i>MISTY1:</i> Developed at Mitsubishi Electric Corp., a block
|
<li> <p><i>MISTY1:</i> Developed at Mitsubishi Electric Corp., a block
|
||||||
cipher using a 128-bit key and 64-bit blocks, and a variable number of
|
cipher using a 128-bit key and 64-bit blocks, and a variable number of
|
||||||
@ -385,7 +385,7 @@ signaling data for emerging mobile communications systems.</p></li>
|
|||||||
<li> <p><i><a href="http://www.kisa.or.kr/seed/seed_eng.html">SEED</a>:</i>
|
<li> <p><i><a href="http://www.kisa.or.kr/seed/seed_eng.html">SEED</a>:</i>
|
||||||
A block cipher using 128-bit blocks and 128-bit keys. Developed by the
|
A block cipher using 128-bit blocks and 128-bit keys. Developed by the
|
||||||
Korea Information Security Agency (KISA) and adopted as a national
|
Korea Information Security Agency (KISA) and adopted as a national
|
||||||
standard encryption algorithm in South Korea. Also described in <a href="http://www.rfc-editor.org/rfc/rfc4009.txt">RFC 4009</a>.</p></li>
|
standard encryption algorithm in South Korea. Also described in <a href="http://www.rfc-editor.org/rfc/rfc4269.txt">RFC 4269</a>.</p></li>
|
||||||
|
|
||||||
<li> <p><i><a href="http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf">Skipjack</a>:</i>
|
<li> <p><i><a href="http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf">Skipjack</a>:</i>
|
||||||
SKC scheme proposed for Capstone. Although the details of the algorithm
|
SKC scheme proposed for Capstone. Although the details of the algorithm
|
||||||
@ -463,11 +463,16 @@ large prime numbers. In fact, large prime numbers, like small prime
|
|||||||
numbers, only have two factors!) The ability for computers to factor
|
numbers, only have two factors!) The ability for computers to factor
|
||||||
large numbers, and therefore attack schemes such as RSA, is rapidly
|
large numbers, and therefore attack schemes such as RSA, is rapidly
|
||||||
improving and systems today can find the prime factors of numbers with
|
improving and systems today can find the prime factors of numbers with
|
||||||
more than 140 digits. The presumed protection of RSA, however, is that
|
more than 200 digits. Nevertheless, if a large number is created from
|
||||||
users can easily increase the key size to always stay ahead of the
|
two prime factors that are roughly the same size, there is no known
|
||||||
computer processing curve. As an aside, the patent for RSA expired in
|
factorization algorithm that will solve the problem in a reasonable
|
||||||
September 2000 which does not appear to have affected RSA's popularity
|
amount of time; a 2005 test to factor a 200-digit number took 1.5 years
|
||||||
one way or the other. A detailed example of RSA is presented below in <a href="#rsamath">Section 5.3</a>.</p></li>
|
and over 50 years of compute time (see the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Integer_factorization"> integer factorization</a>.)
|
||||||
|
Regardless, one presumed protection of RSA is that users can easily
|
||||||
|
increase the key size to always stay ahead of the computer processing
|
||||||
|
curve. As an aside, the patent for RSA expired in September 2000 which
|
||||||
|
does not appear to have affected RSA's popularity one way or the other.
|
||||||
|
A detailed example of RSA is presented below in <a href="#rsamath">Section 5.3</a>.</p></li>
|
||||||
|
|
||||||
<li> <p><i><a href="http://www.rsasecurity.com/rsalabs/faq/3-6-1.html">Diffie-Hellman</a>:</i>
|
<li> <p><i><a href="http://www.rsasecurity.com/rsalabs/faq/3-6-1.html">Diffie-Hellman</a>:</i>
|
||||||
After the RSA algorithm was published, Diffie and Hellman came up with
|
After the RSA algorithm was published, Diffie and Hellman came up with
|
||||||
@ -590,17 +595,7 @@ recovered. Hash algorithms are typically used to provide a <i>digital fingerprin
|
|||||||
of a file's contents, often used to ensure that the file has not been
|
of a file's contents, often used to ensure that the file has not been
|
||||||
altered by an intruder or virus. Hash functions are also commonly
|
altered by an intruder or virus. Hash functions are also commonly
|
||||||
employed by many operating systems to encrypt passwords. Hash
|
employed by many operating systems to encrypt passwords. Hash
|
||||||
functions, then, help preserve the integrity of a file.</font></p>
|
functions, then, provide a measure of the integrity of a file.</font></p>
|
||||||
<p>
|
|
||||||
<font size="3">Hash functions are sometimes misunderstood and some
|
|
||||||
sources claim that no two files can have the same hash value. This
|
|
||||||
isn't true, strictly speaking. Consider a hash function that provides a
|
|
||||||
128-bit hash value. There are, obviously, 2<sup>128</sup> possible hash values. But there are a lot more than 2<sup>128</sup> <i>possible</i>
|
|
||||||
files. Therefore, there have to be multiple files — in fact, there have
|
|
||||||
to be an infinite number of files! — that can have the same 128-bit
|
|
||||||
hash value. The difficulty is <i>finding</i> two files with the same
|
|
||||||
hash! What is, indeed, very hard to do is to try to create a file that
|
|
||||||
has a given hash value so as to force a hash value collision.</font></p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<font size="3">Hash algorithms that are in common use today include:</font></p>
|
<font size="3">Hash algorithms that are in common use today include:</font></p>
|
||||||
@ -616,27 +611,60 @@ manipulation is made to the original data. MD5 has been implemented in
|
|||||||
a large number of products although several weaknesses in the algorithm
|
a large number of products although several weaknesses in the algorithm
|
||||||
were demonstrated by German cryptographer Hans Dobbertin in 1996.</p></li>
|
were demonstrated by German cryptographer Hans Dobbertin in 1996.</p></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</li><li> <p><i>Secure Hash Algorithm (SHA):</i> Algorithm for NIST's
|
</li><li> <p><i>Secure Hash Algorithm (SHA):</i> Algorithm for NIST's
|
||||||
Secure Hash Standard (SHS). SHA-1 produces a 160-bit hash value and was
|
Secure Hash Standard (SHS). SHA-1 produces a 160-bit hash value and was
|
||||||
originally published as FIPS 180-1 and <a href="ftp://ftp.rfc-editor.org/in-notes/rfc3174.txt"> RFC 3174</a>. <a href="http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf"> FIPS 180-2</a>
|
originally published as FIPS 180-1 and <a href="http://www.rfc-editor.org/rfc/rfc3174.txt"> RFC 3174</a>. <a href="http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf"> FIPS 180-2</a>
|
||||||
describes five algorithms in the SHS: SHA-1 plus SHA-224, SHA-256,
|
describes five algorithms in the SHS: SHA-1 plus SHA-224, SHA-256,
|
||||||
SHA-384, and SHA-512 which can produce hash values that are 224, 256,
|
SHA-384, and SHA-512 which can produce hash values that are 224, 256,
|
||||||
384, or 512 bits in length, respectively.</p></li>
|
384, or 512 bits in length, respectively. SHA-224, -256, -384, and -52
|
||||||
|
are also described in <a href="http://www.rfc-editor.org/rfc/rfc4634.txt"> RFC 4634</a>.</p></li>
|
||||||
<li> <p><i><a href="http://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html">RIPEMD</a>:</i> A series of message digests that initially came from the RIPE (RACE Integrity Primitives Evaluation) project. <a href="http://www.esat.kuleuven.ac.be/%7Ecosicart/pdf/AB-9601/AB-9601.pdf">RIPEMD-160</a>
|
<li> <p><i><a href="http://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html">RIPEMD</a>:</i> A series of message digests that initially came from the RIPE (RACE Integrity Primitives Evaluation) project. <a href="http://www.esat.kuleuven.ac.be/%7Ecosicart/pdf/AB-9601/AB-9601.pdf">RIPEMD-160</a>
|
||||||
was designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel,
|
was designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel,
|
||||||
and optimized for 32-bit processors to replace the then-current 128-bit
|
and optimized for 32-bit processors to replace the then-current 128-bit
|
||||||
hash functions. Other versions include RIPEMD-256, RIPEMD-320, and
|
hash functions. Other versions include RIPEMD-256, RIPEMD-320, and
|
||||||
RIPEMD-128.</p></li>
|
RIPEMD-128.</p></li>
|
||||||
|
|
||||||
<li> <p><i><a href="http://www.calyptix.com/technology/haval.php">HAVAL (HAsh of VAriable Length)</a>:</i>
|
<li> <p><i><a href="http://www.calyptix.com/technology/haval.php">HAVAL (HAsh of VAriable Length)</a>:</i>
|
||||||
Designed by Y. Zheng, J. Pieprzyk and J. Seberry, a hash algorithm with
|
Designed by Y. Zheng, J. Pieprzyk and J. Seberry, a hash algorithm with
|
||||||
many levels of security. HAVAL can create hash values that are 128,
|
many levels of security. HAVAL can create hash values that are 128,
|
||||||
160, 192, 224, or 256 bits in length.</p></li>
|
160, 192, 224, or 256 bits in length.</p></li>
|
||||||
|
<li> <p><i><a href="http://paginas.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html"> Whirlpool</a>:</i> A relatively new hash function, designed by V. Rijmen and P.S.L.M. Barreto. Whirlpool operates on messages less than 2<sup>256</sup>
|
||||||
|
bits in length, and produces a message digest of 512 bits. The design
|
||||||
|
of this has function is very different than that of MD5 and SHA-1,
|
||||||
|
making it immune to the same attacks as on those hashes (see below).</p></li>
|
||||||
</font></ul>
|
</font></ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<font size="3">For additional information, see David Hopwood's <a href="http://www.users.zetnet.co.uk/hopwood/crypto/scan/md.html"> MessageDigest Algorithms</a> page.</font></p>
|
<font size="3">Hash functions are sometimes misunderstood and some
|
||||||
|
sources claim that no two files can have the same hash value. This is,
|
||||||
|
in fact, not correct. Consider a hash function that provides a 128-bit
|
||||||
|
hash value. There are, obviously, 2<sup>128</sup> possible hash values. But there are a lot more than 2<sup>128</sup> <i>possible</i>
|
||||||
|
files. Therefore, there have to be multiple files — in fact, there have
|
||||||
|
to be an infinite number of files! — that can have the same 128-bit
|
||||||
|
hash value.</font></p>
|
||||||
|
<p>
|
||||||
|
<font size="3">The difficulty is <i>finding</i> two files with the same
|
||||||
|
hash! What is, indeed, very hard to do is to try to create a file that
|
||||||
|
has a given hash value so as to force a hash value collision — which is
|
||||||
|
the reason that hash functions are used extensively for information
|
||||||
|
security and computer forensics applications. Alas, researchers in 2004
|
||||||
|
found that <i>practical</i> collision attacks could be launched on
|
||||||
|
MD5, SHA-1, and other hash algorithms. At this time, there is no
|
||||||
|
obvious successor to MD5 and SHA-1 that could be put into use quickly;
|
||||||
|
there are so many products using these hash functions that it could
|
||||||
|
take many years to flush out all use of 128- and 160-bit hashes.
|
||||||
|
Readers interested in this problem should read the following:</font></p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<font size="3"><li>Burr, W. (2006, Match/April). Cryptographic hash standards: Where do we go from here? <i>IEEE Security & Privacy</i>, <i>4</i>(2), 88-91.</li>
|
||||||
|
<li>Gutman, P., Naccache, D., & Palmer, C.C. (2005, May/June). When hashes collide. <i>IEEE Security & Privacy</i>, <i>3</i>(3), 68-71.</li>
|
||||||
|
<li>Klima, V. (March 2005) <a href="http://cryptography.hyperlink.cz/md5/MD5_collisions.pdf">"Finding MD5 Collisions - a Toy For a Notebook."</a></li>
|
||||||
|
<li>Thompson, E. (2005, February). MD5 collisions and the impact on computer forensics. <i>Digital Investigation</i>, <i>2</i>(1), 36-40.</li>
|
||||||
|
<li>Wang, X., Feng, D., Lai, X., & Yu, H. (August 2004). <a href="http://eprint.iacr.org/2004/199">"Collisions for Hash Functions MD4, MD5, HAVAL-128 and RIPEMD."</a></li>
|
||||||
|
<li>Wang, X., Yin, Y.L., & Yu, H. (February 2005). <a href="http://theory.csail.mit.edu/%7Eyiqun/shanote.pdf">"Collision Search Attacks on SHA1."</a></li>
|
||||||
|
</font></ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<font size="3">An excellent review of the situation with hash collisions can be found in <a href="http://www.rfc-editor.org/rfc/rfc4270.txt">RFC 4270</a> (by P. Hoffman and B. Schneier, November 2005). And for additional information on hash functions, see David Hopwood's <a href="http://www.users.zetnet.co.uk/hopwood/crypto/scan/md.html"> MessageDigest Algorithms</a> page.</font></p>
|
||||||
|
|
||||||
<font size="3"><a name="why3"><h3>3.4. Why Three Encryption Techniques?</h3></a>
|
<font size="3"><a name="why3"><h3>3.4. Why Three Encryption Techniques?</h3></a>
|
||||||
</font><p>
|
</font><p>
|
||||||
@ -663,7 +691,7 @@ public-key cryptography.
|
|||||||
</font></p>
|
</font></p>
|
||||||
<font size="3"><a name="fig02"></a><br>
|
<font size="3"><a name="fig02"></a><br>
|
||||||
</font><center><table border="1"><tbody><tr><td>
|
</font><center><table border="1"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_3ways.gif">
|
<img src="index_files/crypto_3ways.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 2: Sample application of the three cryptographic techniques for secure communication.</h4>
|
<h4>FIGURE 2: Sample application of the three cryptographic techniques for secure communication.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -972,7 +1000,7 @@ other secure means.
|
|||||||
<br>
|
<br>
|
||||||
<a name="fig03"><br>
|
<a name="fig03"><br>
|
||||||
</a></font></p><center><table border="3" cellpadding="4"><tbody><tr><td>
|
</a></font></p><center><table border="3" cellpadding="4"><tbody><tr><td>
|
||||||
<img src="crypto_files/kerberos.gif">
|
<img src="index_files/kerberos.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 3: Kerberos architecture.</h4>
|
<h4>FIGURE 3: Kerberos architecture.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -1065,7 +1093,7 @@ signature of the certificate issuer, and perhaps other information.
|
|||||||
<br>
|
<br>
|
||||||
<a name="fig04"><br>
|
<a name="fig04"><br>
|
||||||
</a></font></p><center><table border="3" cellpadding="4"><tbody><tr><td>
|
</a></font></p><center><table border="3" cellpadding="4"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_cert.gif">
|
<img src="index_files/crypto_cert.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 4: GTE Cybertrust Global Root-issued certificate as viewed<br>by Netscape Navigator V4.</h4>
|
<h4>FIGURE 4: GTE Cybertrust Global Root-issued certificate as viewed<br>by Netscape Navigator V4.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -1238,6 +1266,11 @@ Standards and Technology (NIST) as standards for the U.S. Government.
|
|||||||
</td><td valign="top" width="60%">A PCMCIA card developed by NSA that
|
</td><td valign="top" width="60%">A PCMCIA card developed by NSA that
|
||||||
implements the Capstone algorithms, intended for use with the Defense
|
implements the Capstone algorithms, intended for use with the Defense
|
||||||
Messaging Service (DMS).
|
Messaging Service (DMS).
|
||||||
|
</td></tr><tr><td valign="top" width="20%">GOST
|
||||||
|
</td><td valign="top" width="60%">GOST is a family of algorithms that
|
||||||
|
is defined in the Russian cryptographic standards. Although most of the
|
||||||
|
specifications are written in Russian, <a href="http://www.rfc-editor.org/rfc/rfc4357.txt">RFC 4357</a> provides supplemental information and specifications so that the algorithms can be used effectively in Internet applications.
|
||||||
|
|
||||||
<a name="tab03-ipsec"></a>
|
<a name="tab03-ipsec"></a>
|
||||||
</td></tr><tr><td valign="top" width="20%"><a href="http://www.ietf.org/html.charters/ipsec-charter.html">IP Security Protocol (IPsec)</a>
|
</td></tr><tr><td valign="top" width="20%"><a href="http://www.ietf.org/html.charters/ipsec-charter.html">IP Security Protocol (IPsec)</a>
|
||||||
</td><td valign="top" width="60%">The IPsec protocol suite is used to
|
</td><td valign="top" width="60%">The IPsec protocol suite is used to
|
||||||
@ -1245,24 +1278,37 @@ provide privacy and authentication services at the IP layer. An
|
|||||||
overview of the protocol suite and of the documents comprising IPsec
|
overview of the protocol suite and of the documents comprising IPsec
|
||||||
can be found in <a href="http://www.rfc-editor.org/rfc/rfc2411.txt">RFC 2411</a>. Other documents include:
|
can be found in <a href="http://www.rfc-editor.org/rfc/rfc2411.txt">RFC 2411</a>. Other documents include:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.rfc-editor.org/rfc/rfc2401.txt">RFC 2401</a>: IP security architecture.
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4301.txt">RFC 4301</a>: IP security architecture.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2402.txt">RFC 2402</a>:
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc4302.txt">RFC 4302</a>:
|
||||||
IP Authentication Header (AH), one of the two primary IPsec functions;
|
IP Authentication Header (AH), one of the two primary IPsec functions;
|
||||||
AH provides connectionless integrity and data origin authentication for
|
AH provides connectionless integrity and data origin authentication for
|
||||||
IP datagrams and protects against replay attacks.
|
IP datagrams and protects against replay attacks.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>: Describes use of the HMAC with MD5 algorithm for data origin authentication and integrity protection in both AH and ESP.
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc4303.txt">RFC 4303</a>:
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2404.txt">RFC 2404</a>: Describes use of the HMAC with SHA-1 algorithm for data origin authentication and integrity protection in both AH and ESP.
|
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2405.txt">RFC 2405</a>: Describes use of DES-CBC (DES in Cipher Block Chaining Mode) for confidentiality in ESP.
|
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2406.txt">RFC 2406</a>:
|
|
||||||
IP Encapsulating Security Payload (ESP), the other primary IPsec
|
IP Encapsulating Security Payload (ESP), the other primary IPsec
|
||||||
function; ESP provides a variety of security services within IPsec.
|
function; ESP provides a variety of security services within IPsec.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2407.txt">RFC 2407</a>: Describes the application of ISAKMP to IPsec.
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc4304.txt">RFC 4304</a>:
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2408.txt">RFC 2408</a>: Describes ISAKMP, a framework for key management and security associations.
|
Extended Sequence Number (ESN) Addendum, allows for negotiation of a
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2409.txt">RFC 2409</a>:
|
32- or 64- bit sequence number, used to detect replay attacks.</li>
|
||||||
The Internet Key Exchange (IKE) algorithm, using part of Oakley and
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4305.txt">RFC 4305</a>: Cryptographic algorithm implementation requirements for ESP and AH.</li>
|
||||||
part of SKEME in conjunction with ISAKMP to obtain authenticated keying
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4306.txt">RFC 4306</a>:
|
||||||
material for use with ISAKMP, and for other security associations such
|
The Internet Key Exchange (IKE) protocol, version 2, providing for
|
||||||
as AH and ESP.
|
mutual authentication and establishing and maintaining security
|
||||||
|
associations.</li>
|
||||||
|
<ul>
|
||||||
|
<li> IKE v1 was described in three separate documents, <a href="http://www.rfc-editor.org/rfc/rfc2407.txt">RFC 2407</a> (application of ISAKMP to IPsec), <a href="http://www.rfc-editor.org/rfc/rfc2408.txt">RFC 2408</a> (ISAKMP, a framework for key management and security associations), and <a href="http://www.rfc-editor.org/rfc/rfc2409.txt">RFC 2409</a>
|
||||||
|
(IKE, using part of Oakley and part of SKEME in conjunction with ISAKMP
|
||||||
|
to obtain authenticated keying material for use with ISAKMP, and for
|
||||||
|
other security associations such as AH and ESP). IKE v1 is obsoleted
|
||||||
|
with the introdcution of IKEv2.</li>
|
||||||
|
</ul>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4307.txt"> RFC 4307</a>: Cryptographic algoritms used with IKEv2.</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4308.txt">RFC 4308</a>: Crypto suites for IPsec, IKE, and IKEv2.</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4309.txt"> RFC 4309</a>: The use of AES in CBC-MAC mode with IPsec ESP.</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4312.txt"> RFC 4312</a>: The use of the Camellia cipher algorithm in IPsec.</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4359.txt"> RFC 4359</a>: The Use of RSA/SHA-1 Signatures within Encapsulating Security Payload (ESP) and Authentication Header (AH).</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc4434.txt"> RFC 4434</a>: Describes AES-XCBC-PRF-128, a pseudo-random function derived from the AES for use with IKE.</li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>: Describes use of the HMAC with MD5 algorithm for data origin authentication and integrity protection in both AH and ESP.
|
||||||
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2405.txt">RFC 2405</a>: Describes use of DES-CBC (DES in Cipher Block Chaining Mode) for confidentiality in ESP.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2410.txt">RFC 2410</a>: Defines use of the NULL encryption algorithm (i.e., provides authentication and integrity without confidentiality) in ESP.
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2410.txt">RFC 2410</a>: Defines use of the NULL encryption algorithm (i.e., provides authentication and integrity without confidentiality) in ESP.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2412.txt">RFC 2412</a>: Describes OAKLEY, a key determination and distribution protocol.
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2412.txt">RFC 2412</a>: Describes OAKLEY, a key determination and distribution protocol.
|
||||||
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2451.txt">RFC 2451</a>: Describes use of Cipher Block Chaining (CBC) mode cipher algorithms with ESP.
|
</li><li><a href="http://www.rfc-editor.org/rfc/rfc2451.txt">RFC 2451</a>: Describes use of Cipher Block Chaining (CBC) mode cipher algorithms with ESP.
|
||||||
@ -1374,7 +1420,19 @@ Windows NT Server running Internet Information Server (IIS) 4.0 with a
|
|||||||
valid SGC certificate. SGC is available in 32-bit Windows versions of
|
valid SGC certificate. SGC is available in 32-bit Windows versions of
|
||||||
Internet Explorer (IE) 4.0, and support for Mac, Unix, and 16-bit
|
Internet Explorer (IE) 4.0, and support for Mac, Unix, and 16-bit
|
||||||
Windows versions of IE is expected in the future.
|
Windows versions of IE is expected in the future.
|
||||||
</td></tr><tr><td valign="top" width="20%"><a href="http://skip.incog.com/">Simple Key-Management for Internet Protocol (SKIP)</a>
|
</td></tr><tr><td valign="top" width="20%"><a href="http://www.rfc-editor.org/rfc/rfc4422.txt">Simple Authentication and Security Layer (SASL)</a>
|
||||||
|
</td><td valign="top" width="60%">(SASL) is a framework for providing
|
||||||
|
authentication and data security services in connection-oriented
|
||||||
|
protocols (a la TCP). It provides a structured interface and allows new
|
||||||
|
protocols to reuse existing authentication mechanisms and allows old
|
||||||
|
protocols to make use of new mechanisms.
|
||||||
|
<p>It has been common practice on the Internet to permit anonymous
|
||||||
|
access to various services, employing a plain-text password using a
|
||||||
|
user name of "anonymous" and a password of an email address or some
|
||||||
|
other identifying information. New IETF protocols disallow plain-text
|
||||||
|
logins. The Anonymous SASL Mechanism (<a href="http://www.rfc-editor.org/rfc/rfc4505.txt">RFC 4505</a>) provides a method for anonymous logins within the SASL framework.
|
||||||
|
|
||||||
|
</p></td></tr><tr><td valign="top" width="20%"><a href="http://skip.incog.com/">Simple Key-Management for Internet Protocol (SKIP)</a>
|
||||||
</td><td valign="top" width="60%">Key management scheme for secure IP
|
</td><td valign="top" width="60%">Key management scheme for secure IP
|
||||||
communication, specifically for IPsec, and designed by Aziz and Diffie.
|
communication, specifically for IPsec, and designed by Aziz and Diffie.
|
||||||
SKIP essentially defines a public key infrastructure for the Internet
|
SKIP essentially defines a public key infrastructure for the Internet
|
||||||
@ -1739,10 +1797,13 @@ Cipher Block Chaining (CBC), Cipher Feedback (CFB), and Output Feedback
|
|||||||
(OFB). Despite all of these options, ECB is the most commonly deployed
|
(OFB). Despite all of these options, ECB is the most commonly deployed
|
||||||
mode of operation.</font></p>
|
mode of operation.</font></p>
|
||||||
<p>
|
<p>
|
||||||
<font size="3">Although other block ciphers will replace DES, it is
|
<font size="3">NIST finally declared DES obsolete in 2004, and withdrew FIPS 46-3, 74, and 81 (<a href="http://csrc.nist.gov/Federal-register/July26-2004-FR-DES-Notice.pdf" target="_blank"><i>Federal Register</i>, July 26, 2004, <i>69</i>(142), 44509-44510</a>).
|
||||||
still interesting to see how DES encryption is performed. Not only is
|
Although other block ciphers will replace DES, it is still interesting
|
||||||
it sort of interesting, but DES remains in many products and we will
|
to see how DES encryption is performed; not only is it sort of neat,
|
||||||
continue to see DES for some years to come.</font></p>
|
but DES was the first crypto scheme commonly seen in non-govermental
|
||||||
|
applications and was the catalyst for modern "public" cryptography. DES
|
||||||
|
remains in many products — and cryptography students and cryptographers
|
||||||
|
will continue to study DES for years to come.</font></p>
|
||||||
|
|
||||||
<p><font size="3"><b>DES Operational Overview</b></font></p>
|
<p><font size="3"><b>DES Operational Overview</b></font></p>
|
||||||
<p>
|
<p>
|
||||||
@ -1756,7 +1817,7 @@ of randomness, or <i>entropy</i>).</font></p>
|
|||||||
|
|
||||||
<font size="3"><a name="fig06"><br>
|
<font size="3"><a name="fig06"><br>
|
||||||
</a></font><center><table border="1"><tbody><tr><td>
|
</a></font><center><table border="1"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_des.gif">
|
<img src="index_files/crypto_des.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 6: DES enciphering algorithm.</h4>
|
<h4>FIGURE 6: DES enciphering algorithm.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -2148,7 +2209,7 @@ nonrepudiation for the classic Internet Protocol (IP). Although
|
|||||||
intended primarily for IP version 6 (IPv6), IPsec can also be employed
|
intended primarily for IP version 6 (IPv6), IPsec can also be employed
|
||||||
by the current version of IP, namely IP version 4 (IPv4).</font></p>
|
by the current version of IP, namely IP version 4 (IPv4).</font></p>
|
||||||
<p>
|
<p>
|
||||||
<font size="3">As shown in <a href="#tab03-ipsec">Table 3</a>, IPsec is described in nearly a dozen RFCs. <a href="http://www.rfc-editor.org/rfc/rfc2401.txt"> RFC 2401</a>, in particular, describes the overall IP security architecture and <a href="http://www.rfc-editor.org/rfc/rfc2411.txt">RFC 2411</a> provides an overview of the IPsec protocol suite and the documents describing it.</font></p>
|
<font size="3">As shown in <a href="#tab03-ipsec">Table 3</a>, IPsec is described in nearly a dozen RFCs. <a href="http://www.rfc-editor.org/rfc/rfc4301.txt"> RFC 4301</a>, in particular, describes the overall IP security architecture and <a href="http://www.rfc-editor.org/rfc/rfc2411.txt">RFC 2411</a> provides an overview of the IPsec protocol suite and the documents describing it.</font></p>
|
||||||
<p>
|
<p>
|
||||||
<font size="3">IPsec can provide either message authentication and/or
|
<font size="3">IPsec can provide either message authentication and/or
|
||||||
encryption. The latter requires more processing than the former, but
|
encryption. The latter requires more processing than the former, but
|
||||||
@ -2173,7 +2234,7 @@ endpoints requires the establishment of two SAs (one in each direction).</font><
|
|||||||
<li>security protocol (AH or ESP) identifier</li>
|
<li>security protocol (AH or ESP) identifier</li>
|
||||||
</font></ul>
|
</font></ul>
|
||||||
<p>
|
<p>
|
||||||
<font size="3">The IP Authentication Header (AH), described in <a href="http://www.rfc-editor.org/rfc/rfc2402.txt">RFC 2402</a>, provides a mechanism for data integrity and data origin authentication for IP packets using HMAC with MD5 (<a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>), HMAC with SHA-1 (<a href="http://www.rfc-editor.org/rfc/rfc2404.txt">RFC 2404</a>), or HMAC with RIPEMD (<a href="http://www.rfc-editor.org/rfc/rfc2857.txt">RFC 2857</a>).</font></p>
|
<font size="3">The IP Authentication Header (AH), described in <a href="http://www.rfc-editor.org/rfc/rfc4302.txt">RFC 4302</a>, provides a mechanism for data integrity and data origin authentication for IP packets using HMAC with MD5 (<a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>), HMAC with SHA-1 (<a href="http://www.rfc-editor.org/rfc/rfc2404.txt">RFC 2404</a>), or HMAC with RIPEMD (<a href="http://www.rfc-editor.org/rfc/rfc2857.txt">RFC 2857</a>). See also <a href="http://www.rfc-editor.org/rfc/rfc4305.txt">RFC 4305</a>.</font></p>
|
||||||
|
|
||||||
<font size="3"><a name="fig10"></a><br>
|
<font size="3"><a name="fig10"></a><br>
|
||||||
</font><center>
|
</font><center>
|
||||||
@ -2190,12 +2251,12 @@ endpoints requires the establishment of two SAs (one in each direction).</font><
|
|||||||
| Sequence Number Field |
|
| Sequence Number Field |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| |
|
| |
|
||||||
+ Authentication Data (variable) |
|
+ Integrity Check Value-ICV (variable) |
|
||||||
| |
|
| |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
</p><h4>FIGURE 10: IPsec Authentication Header format. <i>(From RFC 2402)</i></h4>
|
</p><h4>FIGURE 10: IPsec Authentication Header format. <i>(From RFC 4302)</i></h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
</center>
|
</center>
|
||||||
<font size="3"><br><br>
|
<font size="3"><br><br>
|
||||||
@ -2242,38 +2303,44 @@ algorithm specified by the SA, such as DES, MD5, or SHA-1. Other
|
|||||||
algorithms <i>may</i> also be supported.</li>
|
algorithms <i>may</i> also be supported.</li>
|
||||||
</font></ul>
|
</font></ul>
|
||||||
<p>
|
<p>
|
||||||
<font size="3">The IP Encapsulating Security Payload (ESP), described in <a href="http://www.rfc-editor.org/rfc/rfc2406.txt">RFC 2406</a>,
|
<font size="3">The IP Encapsulating Security Payload (ESP), described in <a href="http://www.rfc-editor.org/rfc/rfc4303.txt">RFC 4303</a>,
|
||||||
provides message integrity and privacy mechanisms in addition to
|
provides message integrity and privacy mechanisms in addition to
|
||||||
authentication. As in AH, ESP uses HMAC with MD5, SHA-1, or RIPEMD
|
authentication. As in AH, ESP uses HMAC with MD5, SHA-1, or RIPEMD
|
||||||
authentication (<a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>/<a href="http://www.rfc-editor.org/rfc/rfc2404.txt">RFC 2404</a>/<a href="http://www.rfc-editor.org/rfc/rfc2857.txt">RFC 2857</a>); privacy is provided using DES-CBC encryption (<a href="http://www.rfc-editor.org/rfc/rfc2405.txt">RFC 2405</a>), NULL encryption (<a href="http://www.rfc-editor.org/rfc/rfc2410.txt">RFC 2410</a>), other CBC-mode algorithms (<a href="http://www.rfc-editor.org/rfc/rfc2451.txt">RFC 2451</a>), or AES (<a href="http://www.rfc-editor.org/rfc/rfc3686.txt">RFC 3686</a>).</font></p>
|
authentication (<a href="http://www.rfc-editor.org/rfc/rfc2403.txt">RFC 2403</a>/<a href="http://www.rfc-editor.org/rfc/rfc2404.txt">RFC 2404</a>/<a href="http://www.rfc-editor.org/rfc/rfc2857.txt">RFC 2857</a>); privacy is provided using DES-CBC encryption (<a href="http://www.rfc-editor.org/rfc/rfc2405.txt">RFC 2405</a>), NULL encryption (<a href="http://www.rfc-editor.org/rfc/rfc2410.txt">RFC 2410</a>), other CBC-mode algorithms (<a href="http://www.rfc-editor.org/rfc/rfc2451.txt">RFC 2451</a>), or AES (<a href="http://www.rfc-editor.org/rfc/rfc3686.txt">RFC 3686</a>). See also <a href="http://www.rfc-editor.org/rfc/rfc4305.txt">RFC 4305</a> and <a href="http://www.rfc-editor.org/rfc/rfc4308.txt">RFC 4308</a>.</font></p>
|
||||||
|
|
||||||
<font size="3"><a name="fig11"></a><br>
|
<font size="3"><a name="fig11"></a><br>
|
||||||
</font><center>
|
</font><center>
|
||||||
<table border="3" cellpadding="4">
|
<table border="3" cellpadding="4">
|
||||||
<tbody><tr><td width="600">
|
<tbody><tr><td width="675">
|
||||||
<pre>
|
<pre>
|
||||||
0 1 2 3
|
0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
|
||||||
| Security Parameters Index (SPI) |
|
| Security Parameters Index (SPI) | ^Int.
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
|
||||||
| Sequence Number |
|
| Sequence Number | |ered
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ----
|
||||||
| Payload Data (variable) |
|
| Payload Data* (variable) | | ^
|
||||||
~ ~
|
~ ~ | |
|
||||||
| |
|
| | |Conf.
|
||||||
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
|
||||||
| | Padding (0-255 bytes) |
|
| | Padding (0-255 bytes) | |ered*
|
||||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|
||||||
| | Pad Length | Next Header |
|
| | Pad Length | Next Header | v v
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ------
|
||||||
| Authentication Data (variable) |
|
| Integrity Check Value-ICV (variable) |
|
||||||
~ ~
|
~ ~
|
||||||
| |
|
| |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
* If included in the Payload field, cryptographic synchronization
|
||||||
|
data, e.g., an Initialization Vector (IV), usually is not
|
||||||
|
encrypted per se, although it often is referred to as being
|
||||||
|
being part of the ciphertext.
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
</p><h4>FIGURE 11: IPsec Encapsulating Security Payload format. <i>(From RFC 2406)</i></h4>
|
</p><h4>FIGURE 11: IPsec Encapsulating Security Payload format. <i>(From RFC 4303)</i></h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
</center>
|
</center>
|
||||||
<font size="3"><br><br>
|
<font size="3"><br><br>
|
||||||
@ -2322,60 +2389,62 @@ This mode of operation is supported by both hosts and security gateways.</font><
|
|||||||
<font size="3"><a name="fig12"></a><br>
|
<font size="3"><a name="fig12"></a><br>
|
||||||
</font><center>
|
</font><center>
|
||||||
<table border="3" cellpadding="4">
|
<table border="3" cellpadding="4">
|
||||||
<tbody><tr><td width="600">
|
<tbody><tr><td width="675">
|
||||||
<pre>
|
<pre>
|
||||||
<b>ORIGINAL PACKET BEFORE APPLYING AH</b>
|
<b>ORIGINAL PACKET BEFORE APPLYING AH</b>
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
<b>IPv4</b> |orig IP hdr | | |
|
<b>IPv4</b> |orig IP hdr | | |
|
||||||
|(any options)| TCP | Data |
|
|(any options)| TCP | Data |
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
<b>IPv6</b> | | ext hdrs | | |
|
<b>IPv6</b> | | ext hdrs | | |
|
||||||
| orig IP hdr |if present| TCP | Data |
|
| orig IP hdr |if present| TCP | Data |
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
<b>AFTER APPLYING AH (TRANSPORT MODE)</b>
|
||||||
|
|
||||||
|
-------------------------------------------------------
|
||||||
|
<b>IPv4</b> |original IP hdr (any options) | AH | TCP | Data |
|
||||||
|
-------------------------------------------------------
|
||||||
|
|<- mutable field processing ->|<- immutable fields ->|
|
||||||
|
|<----- authenticated except for mutable fields ----->|
|
||||||
|
|
||||||
|
------------------------------------------------------------
|
||||||
|
<b>IPv6</b> | |hop-by-hop, dest*, | | dest | | |
|
||||||
|
|orig IP hdr |routing, fragment. | AH | opt* | TCP | Data |
|
||||||
|
------------------------------------------------------------
|
||||||
|
|<--- mutable field processing -->|<-- immutable fields -->|
|
||||||
|
|<---- authenticated except for mutable fields ----------->|
|
||||||
|
|
||||||
|
* = if present, could be before AH, after AH, or both
|
||||||
|
|
||||||
|
|
||||||
<b>AFTER APPLYING AH (TRANSPORT MODE)</b>
|
<b>AFTER APPLYING AH (TUNNEL MODE)</b>
|
||||||
|
|
||||||
---------------------------------
|
----------------------------------------------------------------
|
||||||
<b>IPv4</b> |orig IP hdr | | | |
|
<b>IPv4</b> | | | orig IP hdr* | | |
|
||||||
|(any options)| AH | TCP | Data |
|
|new IP header * (any options) | AH | (any options) |TCP| Data |
|
||||||
---------------------------------
|
----------------------------------------------------------------
|
||||||
|<------- authenticated ------->|
|
|<- mutable field processing ->|<------ immutable fields ----->|
|
||||||
except for mutable fields
|
|<- authenticated except for mutable fields in the new IP hdr->|
|
||||||
|
|
||||||
------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
<b>IPv6</b> | |hop-by-hop, dest*, | | dest | | |
|
<b>IPv6</b> | | ext hdrs*| | | ext hdrs*| | |
|
||||||
|orig IP hdr |routing, fragment. | AH | opt* | TCP | Data |
|
|new IP hdr*|if present| AH |orig IP hdr*|if present|TCP|Data|
|
||||||
------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|<---- authenticated except for mutable fields ----------->|
|
|<--- mutable field -->|<--------- immutable fields -------->|
|
||||||
|
| processing |
|
||||||
|
|<-- authenticated except for mutable fields in new IP hdr ->|
|
||||||
|
|
||||||
* = if present, could be before AH, after AH, or both
|
* = if present, construction of outer IP hdr/extensions and
|
||||||
|
modification of inner IP hdr/extensions is discussed in
|
||||||
|
the Security Architecture document.
|
||||||
|
|
||||||
|
|
||||||
<b>AFTER APPLYING AH (TUNNEL MODE)</b>
|
|
||||||
|
|
||||||
------------------------------------------------
|
|
||||||
<b>IPv4</b> | new IP hdr* | | orig IP hdr* | | |
|
|
||||||
|(any options)| AH | (any options) |TCP | Data |
|
|
||||||
------------------------------------------------
|
|
||||||
|<- authenticated except for mutable fields -->|
|
|
||||||
|
|
||||||
| in the new IP hdr |
|
|
||||||
|
|
||||||
--------------------------------------------------------------
|
|
||||||
<b>IPv6</b> | | ext hdrs*| | | ext hdrs*| | |
|
|
||||||
|new IP hdr*|if present| AH |orig IP hdr*|if present|TCP|Data|
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|<-- authenticated except for mutable fields in new IP hdr ->|
|
|
||||||
|
|
||||||
* = construction of outer IP hdr/extensions and modification
|
|
||||||
of inner IP hdr/extensions is discussed below.
|
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
</p><h4>FIGURE 12: IPsec tunnel and transport modes for AH. <i>(Adapted from RFC 2402)</i></h4>
|
</p><h4>FIGURE 12: IPsec tunnel and transport modes for AH. <i>(Adapted from RFC 4302)</i></h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
</center>
|
</center>
|
||||||
<font size="3"><br><br>
|
<font size="3"><br><br>
|
||||||
@ -2397,7 +2466,7 @@ Note, in particular, that the address fields are <i>not</i> mutable.</font></p>
|
|||||||
<a name="fig13"></a><br>
|
<a name="fig13"></a><br>
|
||||||
</font><center>
|
</font><center>
|
||||||
<table border="3" cellpadding="4">
|
<table border="3" cellpadding="4">
|
||||||
<tbody><tr><td width="600">
|
<tbody><tr><td width="675">
|
||||||
<pre>
|
<pre>
|
||||||
<b>ORIGINAL PACKET BEFORE APPLYING ESP</b>
|
<b>ORIGINAL PACKET BEFORE APPLYING ESP</b>
|
||||||
|
|
||||||
@ -2416,17 +2485,17 @@ Note, in particular, that the address fields are <i>not</i> mutable.</font></p>
|
|||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
<b>IPv4</b> |orig IP hdr | ESP | | | ESP | ESP|
|
<b>IPv4</b> |orig IP hdr | ESP | | | ESP | ESP|
|
||||||
|(any options)| Hdr | TCP | Data | Trailer |Auth|
|
|(any options)| Hdr | TCP | Data | Trailer | ICV|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|<----- encrypted ---->|
|
|<---- encryption ---->|
|
||||||
|<------ authenticated ----->|
|
|<-------- integrity ------->|
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
<b>IPv6</b> | orig |hop-by-hop,dest*,|ESP|dest| | | ESP | ESP|
|
<b>IPv6</b> | orig |hop-by-hop,dest*,| |dest| | | ESP | ESP|
|
||||||
|IP hdr|routing,fragment.|hdr|opt*|TCP|Data|Trailer|Auth|
|
|IP hdr|routing,fragment.|ESP|opt*|TCP|Data|Trailer| ICV|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|<---- encrypted ---->|
|
|<--- encryption ---->|
|
||||||
|<---- authenticated ---->|
|
|<------ integrity ------>|
|
||||||
|
|
||||||
* = if present, could be before ESP, after ESP, or both
|
* = if present, could be before ESP, after ESP, or both
|
||||||
|
|
||||||
@ -2434,24 +2503,27 @@ Note, in particular, that the address fields are <i>not</i> mutable.</font></p>
|
|||||||
<b>AFTER APPLYING ESP (TUNNEL MODE)</b>
|
<b>AFTER APPLYING ESP (TUNNEL MODE)</b>
|
||||||
|
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
<b>IPv4</b> | new IP hdr | ESP | orig IP hdr | | | ESP | ESP|
|
<b>IPv4</b> | new IP hdr+ | | orig IP hdr+ | | | ESP | ESP|
|
||||||
|(any options)| hdr | (any options) |TCP|Data|Trailer|Auth|
|
|(any options)| ESP | (any options) |TCP|Data|Trailer| ICV|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|<--------- encrypted ---------->|
|
|<--------- encryption --------->|
|
||||||
|<----------- authenticated ---------->|
|
|<------------- integrity ------------>|
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
<b>IPv6</b> | new+ |new ext |ESP| orig+|orig ext | | | ESP | ESP|
|
<b>IPv6</b> | new+ |new ext | | orig+|orig ext | | | ESP | ESP|
|
||||||
|IP hdr| hdrs+ |hdr|IP hdr| hdrs+ |TCP|Data|Trailer|Auth|
|
|IP hdr| hdrs+ |ESP|IP hdr| hdrs+ |TCP|Data|Trailer| ICV|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|<--------- encrypted ----------->|
|
|<--------- encryption ---------->|
|
||||||
|<---------- authenticated ---------->|
|
|<------------ integrity ------------>|
|
||||||
|
|
||||||
|
+ = if present, construction of outer IP hdr/extensions and
|
||||||
|
modification of inner IP hdr/extensions is discussed in
|
||||||
|
the Security Architecture document.
|
||||||
|
|
||||||
+ = if present
|
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
</p><h4>FIGURE 13: IPsec tunnel and transport modes for ESP. <i>(Adapted from RFC 2406)</i></h4>
|
</p><h4>FIGURE 13: IPsec tunnel and transport modes for ESP. <i>(Adapted from RFC 4303)</i></h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
</center>
|
</center>
|
||||||
<font size="3"><br><br>
|
<font size="3"><br><br>
|
||||||
@ -2563,7 +2635,7 @@ found; both are supported by most common browsers (Figure 14).</font></p>
|
|||||||
|
|
||||||
<font size="3"><a name="fig14"></a><br>
|
<font size="3"><a name="fig14"></a><br>
|
||||||
</font><center><table border="1"><tbody><tr><td>
|
</font><center><table border="1"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_sslv3.gif">
|
<img src="index_files/crypto_sslv3.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 14: SSL v3 configuration screen (Netscape Navigator).</h4>
|
<h4>FIGURE 14: SSL v3 configuration screen (Netscape Navigator).</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -2573,10 +2645,9 @@ found; both are supported by most common browsers (Figure 14).</font></p>
|
|||||||
<font size="3">In 1997, SSL v3 was found to be breakable. By this time,
|
<font size="3">In 1997, SSL v3 was found to be breakable. By this time,
|
||||||
the Internet Engineering Task Force (IETF) had already started work on
|
the Internet Engineering Task Force (IETF) had already started work on
|
||||||
a new, non-proprietary protocol called Transport Layer Security (TLS),
|
a new, non-proprietary protocol called Transport Layer Security (TLS),
|
||||||
described in <a href="http://www.rfc-editor.org/rfc/rfc2246.txt">RFC 2246</a>.
|
described in <a href="http://www.rfc-editor.org/rfc/rfc2246.txt">RFC 2246</a>. TLS extends SSL and supports additional crypto schemes, such as Diffie-Hellman key exchange and DSS digital signatures; <a href="http://www.rfc-editor.org/rfc/rfc4279.txt">RFC 4279</a>
|
||||||
TLS extends SSL and supports additional crypto schemes, such as
|
describes the pre-shared key crypto schemes supported by TLS. TLS is
|
||||||
Diffie-Hellman key exchange and DSS digital signatures. TLS is backward
|
backward compatible with SSL (and, in fact, is recognized as SSL v3.1).</font></p>
|
||||||
compatible with SSL (and, in fact, is recognized as SSL v3.1).</font></p>
|
|
||||||
|
|
||||||
<font size="3"><a name="fig15"></a><br>
|
<font size="3"><a name="fig15"></a><br>
|
||||||
</font><center><table border="1"><tbody><tr><td>
|
</font><center><table border="1"><tbody><tr><td>
|
||||||
@ -2773,7 +2844,7 @@ changes the shape of the curve, and small changes in these parameters
|
|||||||
can result in major changes in the set of (x,y) solutions.</p>
|
can result in major changes in the set of (x,y) solutions.</p>
|
||||||
<a name="fig16"></a><br>
|
<a name="fig16"></a><br>
|
||||||
<center><table border="1"><tbody><tr><td>
|
<center><table border="1"><tbody><tr><td>
|
||||||
<img src="crypto_files/crypto_ecc.gif">
|
<img src="index_files/crypto_ecc.gif">
|
||||||
<br><br>
|
<br><br>
|
||||||
<h4>FIGURE 16: Elliptic curve addition.</h4>
|
<h4>FIGURE 16: Elliptic curve addition.</h4>
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
@ -3545,6 +3616,7 @@ New York: Macmillan, 1983.
|
|||||||
</li><li>Stallings, W. <i>Cryptography and Network Security: Principles and Practice</i>, 4th ed. Englewood Cliffs (NJ): Prentice Hall, 2006.
|
</li><li>Stallings, W. <i>Cryptography and Network Security: Principles and Practice</i>, 4th ed. Englewood Cliffs (NJ): Prentice Hall, 2006.
|
||||||
</li><li>_____, (ed.) <i>Practical Cryptography for Data Internetworks.</i> Los Alamitos (CA): IEEE Computer Society Press, 1996.
|
</li><li>_____, (ed.) <i>Practical Cryptography for Data Internetworks.</i> Los Alamitos (CA): IEEE Computer Society Press, 1996.
|
||||||
</li><li>Trappe, W. & Washington, L.C. <i>Introduction to Cryptography with Codin Theory</i>, 2nd ed. Upper Saddle River (NJ): Pearson Prentice Hall, 2006.
|
</li><li>Trappe, W. & Washington, L.C. <i>Introduction to Cryptography with Codin Theory</i>, 2nd ed. Upper Saddle River (NJ): Pearson Prentice Hall, 2006.
|
||||||
|
</li><li>Young, A. & Yung, M. <i>Malicious Cryptography: Exposing Cryptovirology</i>. New York: John Wiley & Sons, 2004.
|
||||||
<br><br>
|
<br><br>
|
||||||
</li><li>On the Web:
|
</li><li>On the Web:
|
||||||
<ul>
|
<ul>
|
||||||
@ -3600,14 +3672,14 @@ jokers...) called the <a href="http://www.counterpane.com/solitaire.html">Solita
|
|||||||
|
|
||||||
<table align="center" border="0">
|
<table align="center" border="0">
|
||||||
<tbody><tr>
|
<tbody><tr>
|
||||||
<td><img src="crypto_files/crypto_2600des.gif">
|
<td><img src="index_files/crypto_2600des.gif">
|
||||||
</td><td>
|
</td><td>
|
||||||
<p>
|
<p>
|
||||||
Finally, I am not in the clothing business although I do have an
|
Finally, I am not in the clothing business although I do have an
|
||||||
impressive t-shirt collection (over 350 and counting!). If you want to
|
impressive t-shirt collection (over 350 and counting!). If you want to
|
||||||
proudly wear the DES (well, actually the IDEA) encryption algorithm, be
|
proudly wear the DES (well, actually the IDEA) encryption algorithm, be
|
||||||
sure to see <i>2600 Magazine</i>'s DES Encryption Shirt, found at <a href="http://store.yahoo.com/2600hacker/desenshir.html"> <i>http://store.yahoo.com/2600hacker/desenshir.html</i></a> (left). A t-shirt with Adam Back's RSA Perl code can be found at <a href="http://www.cypherspace.org/%7Eadam/uk-shirt.html"> <i>http://www.cypherspace.org/~adam/uk-shirt.html</i></a> (right).</p>
|
sure to see <i>2600 Magazine</i>'s DES Encryption Shirt, found at <a href="http://store.yahoo.com/2600hacker/desenshir.html"> <i>http://store.yahoo.com/2600hacker/desenshir.html</i></a> (left). A t-shirt with Adam Back's RSA Perl code can be found at <a href="http://www.cypherspace.org/%7Eadam/uk-shirt.html"> <i>http://www.cypherspace.org/~adam/uk-shirt.html</i></a> (right).</p>
|
||||||
</td><td><img src="crypto_files/crypto_backrsa.jpg">
|
</td><td><img src="index_files/crypto_backrsa.jpg">
|
||||||
</td></tr></tbody></table>
|
</td></tr></tbody></table>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
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 '`hostname`'</h1>"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user