1
0
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:
cameronrich 2006-12-07 20:33:16 +00:00
parent dabdec8fcc
commit ce893c517d
8 changed files with 743 additions and 650 deletions

View File

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

View File

@ -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).

View File

@ -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);

View File

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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 &#8212; in fact, there have
to be an infinite number of files! &#8212; 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 &#8212; in fact, there have
to be an infinite number of files! &#8212; 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 &#8212; 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 &amp; Privacy</i>, <i>4</i>(2), 88-91.</li>
<li>Gutman, P., Naccache, D., &amp; Palmer, C.C. (2005, May/June). When hashes collide. <i>IEEE Security &amp; 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., &amp; 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., &amp; 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 &#8212; 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 |
-------------------------------------------------------
|&lt;- mutable field processing -&gt;|&lt;- immutable fields -&gt;|
|&lt;----- authenticated except for mutable fields -----&gt;|
------------------------------------------------------------
<b>IPv6</b> | |hop-by-hop, dest*, | | dest | | |
|orig IP hdr |routing, fragment. | AH | opt* | TCP | Data |
------------------------------------------------------------
|&lt;--- mutable field processing --&gt;|&lt;-- immutable fields --&gt;|
|&lt;---- authenticated except for mutable fields -----------&gt;|
* = 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 |
--------------------------------- ----------------------------------------------------------------
|&lt;------- authenticated -------&gt;| |&lt;- mutable field processing -&gt;|&lt;------ immutable fields -----&gt;|
except for mutable fields |&lt;- authenticated except for mutable fields in the new IP hdr-&gt;|
------------------------------------------------------------ --------------------------------------------------------------
<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|
------------------------------------------------------------ --------------------------------------------------------------
|&lt;---- authenticated except for mutable fields -----------&gt;| |&lt;--- mutable field --&gt;|&lt;--------- immutable fields --------&gt;|
| processing |
|&lt;-- authenticated except for mutable fields in new IP hdr -&gt;|
* = 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 |
------------------------------------------------
|&lt;- authenticated except for mutable fields --&gt;|
| 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|
--------------------------------------------------------------
|&lt;-- authenticated except for mutable fields in new IP hdr -&gt;|
* = 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|
------------------------------------------------- -------------------------------------------------
|&lt;----- encrypted ----&gt;| |&lt;---- encryption ----&gt;|
|&lt;------ authenticated -----&gt;| |&lt;-------- integrity -------&gt;|
--------------------------------------------------------- ---------------------------------------------------------
<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|
--------------------------------------------------------- ---------------------------------------------------------
|&lt;---- encrypted ----&gt;| |&lt;--- encryption ----&gt;|
|&lt;---- authenticated ----&gt;| |&lt;------ integrity ------&gt;|
* = 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|
----------------------------------------------------------- -----------------------------------------------------------
|&lt;--------- encrypted ----------&gt;| |&lt;--------- encryption ---------&gt;|
|&lt;----------- authenticated ----------&gt;| |&lt;------------- integrity ------------&gt;|
------------------------------------------------------------ ------------------------------------------------------------
<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|
------------------------------------------------------------ ------------------------------------------------------------
|&lt;--------- encrypted -----------&gt;| |&lt;--------- encryption ----------&gt;|
|&lt;---------- authenticated ----------&gt;| |&lt;------------ integrity ------------&gt;|
+ = 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. &amp; 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. &amp; 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. &amp; Yung, M. <i>Malicious Cryptography: Exposing Cryptovirology</i>. New York: John Wiley &amp; 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>

View File

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