Hi,

Thanks for the help, but I'm still having problems.  Calling SSL_ForceHandshake following SSL_ResetHandshake fails with -8179.  If I avoid this (which I assume shouldn't be needed anyways, as polling should just not return until I can successfully perform IO?) and try polling for write, the poll succeeds but PR_Write returns -1 and sets the nspr error to -8179 again.  The same happens with reads.

Please see my new and improved silly test script below :)

-Alex
-- 
 Please do not bomb innocent people.


#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>

#include <nspr.h>
#include <prthread.h>
#include <private/pprio.h>

#include "nss.h"
#include <ssl.h>
#include <pk11func.h>

static void
nspr_poll (PRFileDesc *ssl_fdesc, short flags) 
{
	int result;
	PRPollDesc pd;
	
	pd.fd = ssl_fdesc; 
	pd.in_flags = flags | PR_POLL_ERR | PR_POLL_NVAL | PR_POLL_HUP; 

	while (1) {
		result = PR_Poll (&pd, 1, PR_INTERVAL_NO_WAIT);

		if (result == 0)
			continue;

		if (result == -1) {
			printf ("Failed!\n");
			exit (1);
		} else if (pd.out_flags & PR_POLL_ERR) {
			printf ("Poll error!\n");
			exit (1);
		} else if (pd.out_flags & PR_POLL_NVAL) {
			printf ("Invalid FD!\n");
			exit (1);
		} else if (pd.out_flags & PR_POLL_HUP) {
			printf ("Connection Died!\n");
			exit (1);
		} else {
			printf ("OK\n");
			break;
		}

		printf (".");
	}
}

int 
main (int argc, char **argv)
{
	char *nss_dir = "/home/orph/evolution";
	PRFileDesc *ssl_fdesc;
	int sockfd;
	struct hostent *host;
	struct sockaddr_in sa;
	int result;
	unsigned char buf [8192];

	if (argc < 3) {
		printf ("Usage: testnss hostname content");
		exit (1);
	}

	printf ("Creating socket\n");

	sockfd = socket (AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		printf ("socket() failed\n");
		exit (1);
	}

	printf ("Looking up hostname: %s\n", argv [1]);

	host = gethostbyname (argv [1]);
	if (!host) {
		printf ("cannot resolve hostname\n");
		exit (1);
	}

	sa.sin_family = host->h_addrtype;
	sa.sin_port = htons (443);
	memcpy (&sa.sin_addr, host->h_addr, host->h_length);

	printf ("Connecting\n");

	if (connect (sockfd, &sa, sizeof (sa)) < 0) {
		printf ("connect() failed\n");
		exit (1);
	}

	printf ("Calling NSS_InitReadWrite\n");

	if (NSS_InitReadWrite (nss_dir) != SECSuccess) {
		if (NSS_NoDB_Init (nss_dir) == SECFailure) {
			printf ("Unable to initialize NSS SSL Library.");
			exit (1);
		}
	}

	NSS_SetDomesticPolicy ();

        SSL_OptionSetDefault (SSL_ENABLE_SSL2, PR_TRUE);
        SSL_OptionSetDefault (SSL_ENABLE_SSL3, PR_TRUE);
        SSL_OptionSetDefault (SSL_ENABLE_TLS, PR_TRUE);
        SSL_OptionSetDefault (SSL_V2_COMPATIBLE_HELLO, PR_TRUE /* maybe? */);

	printf ("Calling PR_ImportTCPSocket\n");

	ssl_fdesc = PR_ImportTCPSocket (sockfd);
	if (!ssl_fdesc) {
		printf ("SSL socket creation failure");
		exit (1);
	}

	printf ("Calling SSL_ImportFD\n");

	ssl_fdesc = SSL_ImportFD (NULL, ssl_fdesc);
	if (!ssl_fdesc) {
		printf ("SSL object creation failure.");
		exit (1);
	}

	SSL_OptionSet (ssl_fdesc, SSL_SECURITY, PR_TRUE);
	SSL_OptionSet (ssl_fdesc, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
        SSL_SetURL (ssl_fdesc, argv [1]);
	
	printf ("Calling SSL_ResetHandshake\n");

	if (SSL_ResetHandshake (ssl_fdesc, 0) == PR_FAILURE) {
		printf ("SSL handshake failure.");
		exit (1);
	}

	/* -- Hopefully don't need this. Fails anyway.
	if (SSL_ForceHandshake (ssl_fdesc) == PR_FAILURE) {
		printf ("SSL forced handshake failure: ");
		PR_GetErrorText (buf);
		printf ("nspr error %d: %s, oserr: %d\n", 
			PR_GetError (), 
			buf,
			PR_GetOSError ());
		exit (1);
	}
	*/

	printf ("Polling for Write: ");
	nspr_poll (ssl_fdesc, PR_POLL_WRITE);

	printf ("Writing: %s\n", argv [2]);

	PR_SetError (0, 0);

	do {
		result = PR_Write (ssl_fdesc, argv [2], strlen (argv [2]));
	} while (result < 0 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR);

	if (result < 0) {
		PR_GetErrorText (buf);
		printf ("Write failed: %d, nspr error %d: %s, oserr: %d\n", 
			result, 
			PR_GetError (), 
			buf,
			PR_GetOSError ());
		exit (1);
	}

	printf ("Polling for Read: ");
	nspr_poll (ssl_fdesc, PR_POLL_READ);

	printf ("Reading\n");

	do {
		result = PR_Read (ssl_fdesc, buf, sizeof (buf));
	} while (result < 0 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR);

	if (result < 0) {
		PR_GetErrorText (buf);
		printf ("Read failed: %d, nspr error %d: %s, oserr: %d\n", 
			result, 
			PR_GetError (), 
			buf,
			PR_GetOSError ());
		exit (1);
	} else if (result == 0) {
		printf ("Read 0 bytes\n");
	}

	buf [result] = '\0';

	printf ("Read %s\n", buf);

	return 0;
}

Reply via email to