Subject: Amiga Apache-SSL??!
To: None <port-amiga@NetBSD.ORG>
From: None <sudog@dcss.douglas.bc.ca>
List: port-amiga
Date: 05/09/1998 18:06:31
I've been banging my head against a wall trying to figure out why in the
world my compilation of Apache-SSL keeps coredumping on me when it first
tries to initialize itself before actually opening a port and serving
data.

I have scraped through a gdb session and found that the SSL code at one
point invokes the strlen() function with a (0) value. strlen tries to find
the length of the value, but since (0) is presumably not in the program's
addressing space, it segmentation faults. Is this on purpose? Should
strlen not be checking for this sort of thing? What's the programming
commandment again...

-------------------
2	Thou shalt not follow the NULL pointer, for chaos and madness 
	await thee at its end.
-------------------

And yet in strlen(), in /usr/src/sys/lib/libkern/strlen.c we find the
following evil code:

-------------------
size_t
strlen(str)
        const char *str;
{
        register const char *s;
        for (s = str; *s; ++s);
        return(s - str);
}
-------------------

Hrm..  I realize this is in the spirit of optimization.. but hark, from
the annotated version:

-------------------
     various silly and spurious grounds, such as blind worship of the
     Little Tin God (also known as ``Efficiency''). While it is true
     that some features of the C libraries were ill-advised, by and
-------------------

Sorry. I really couldn't resist. I'll do better next time I promise.
In any case, perhaps a better version of strlen() would be as follows. One
extra if statement, and we get a working SSLeay-0.9.0!

-------------------
size_t
strlen(str)
	const chat *str;
{
	register cont shat *s;
	if (s) {
		for (s = str; *s; ++s);
	}
	return(s - str);
}
-------------------

Anyhow, for what it's worth, here're my gdb stack frames:

--------------------
(gdb) bt
#0  0x80de9f2 in strlen ()
#1  0x40772 in ERR_add_error_data ()
#2  0x3e0fa in file_ctrl ()
#3  0x3d5fc in BIO_ctrl ()
#4  0x2cfc2 in SSL_load_client_CA_file ()
#5  0x2802e in GetCertificateAndKey (s=0x8e034, pConfig=0x8e30c)
    at apache_ssl.c:750
#6  0x281ea in InitSSLServer (s=0x8e034, p=0x8e00c) at apache_ssl.c:833
#7  0xb12a in init_modules (p=0x8e00c, s=0x8e034) at http_config.c:1116
#8  0x64f6 in main (argc=3, argv=0xdfffa98) at http_main.c:2520
(gdb)

root:battle>/usr/include/m68k 20 ]uname -a
NetBSD battle.war.com 1.3 NetBSD 1.3 (BATTLE) #1: Sun Feb  1 18:02:00 PST
1998     root@battle.war.com:/usr/src/sys/arch/amiga/compile/BATTLE amiga
root:battle>/usr/include/m68k 21 ]
--------------------

A further investigation reveals that ERR_add_error_data is a function in
the SSL crypto library in its error-handling section which appears to add
a small string to the beginning of another string. It uses the va_start
and other variable argument macros (functions?) to get the list of
arguments.  Why would one of these returns be a zero? See the snippet
below: 

------------------------
void ERR_add_error_data( VAR_PLIST(int , num))
VAR_ALIST
        {
        VAR_BDEFN(args, int, num);
        int i,n,s;
        char *str,*p,*a;

        s=64;
        str=Malloc(s+1);
        if (str == NULL) return;
        str[0]='\0';

        VAR_INIT(args,int,num);
        n=0;
        for (i=0; i<num; i++)
                {
                VAR_ARG(args,char *,a);
/********** right here, `a' eventually turns into a `0' *****/
                n+=strlen(a);
/************************************************************/
                if (n > s)
                        {
                        s=n+20;
                        p=Realloc(str,s+1);
                        if (p == NULL)
                                {
                                Free(str);
                                return;
                                }
                        else
                                str=p;
                        }
                strcat(str,a);
                }
        ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);

        VAR_END( args );
        }
------------------

Notice my helpful comment! I've added a little fprintf(stderr,"a is %d\n",
a); to assist me, and it turns zero right before the core dump. :)
I then wrote a small program that looked like this:

main(){printf("%d\n",strlen(0));}

and compiled and ran it. Core dump! (Kind of a big core dump too.. 140K?
Hrm..)

The VAR_INIT and so forth are defined in a header file as below:

------------------
#define VAR_PLIST(arg1type,arg1)    arg1type arg1, ...
#define VAR_ALIST
#define VAR_BDEFN(args,arg1type,arg1)   va_list args
#define VAR_INIT(args,arg1type,arg1)    va_start(args,arg1);
#define VAR_ARG(args,type,arg)  arg=va_arg(args,type)
#define VAR_END(args)           va_end(args);
------------------

So! After all that, I've come to the conclusion that I really don't know
what I'm doing.. I'm probably missing the snip of code which actually
calls the ERR_*() function.. but I'm a lamer and I can't find it anywhere.

Are the varargs macros being used incorrectly here?

Anyway, I'm sure I can get this working okay eventually, it's just a  pain
to keep having to stop to smell the roses when I really want to get my
hands dirty with a nice (secure? ;) SSL-based apache server running on my
Amiga. God porting stuff is a pain in the butt.

Also, tell me if I should be forwarding this note anywhere else.

Thanks,

Marc Tooley
tooleym@douglas.bc.ca
P.S. The archives I'm using are:
	SSLeay-0.9.0
	apache_1.2.6
	apache_1.2.6+ssl_1.16
All available from ftp.replay.com I think. see http://www.apache-ssl.org
for more details.

P.P.S. Thanks for any help anyone can provide. I can easily and quickly
respond to technical questions--is there a pointer or something someone
can offer in this? Has anyone been successful in implementing Apache-SSL
on an Amiga?