Hi,

I am trying to import a newly connected Unix socket fd using
PR_ImportTCPSocket(), to then use NSS for SSL.  I am using the following
sequence:

        PR_Init
        NSS_InitReadWrite
        NSS_SetDomesticPolicy
        ...
        socket
        connect
        ...
        PR_ImportTCPSocket
        SSL_ImportFD
        SSL_OptionSet (SSL_SECURITY)
        SSL_OptionSet (SSL_HANDSHAKE_AS_CLIENT)
        SSL_SetURL
        SSL_ForceHandshake
        ...
        PR_Write

All of these succeed (SECSuccess is returned and PR_GetError returns
0).  However when I call PR_Write, only the plaintext message is written
to the socket.  The server then terminates the connection.

PR_Write eventually calls ssl2_SendClear (which seems to be a fallback)
to actually write the data.  At a glance the sslSocket has no version or
handshake data.

Attached is a quick example which demonstrates the behaviour.

Please help.

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

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

	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 PR_Init\n");

	PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 10);

	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? */);

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

	ssl_fdesc = SSL_ImportFD (NULL, 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]);
	
	if (SSL_ForceHandshake (ssl_fdesc) == PR_FAILURE) {
		printf ("SSL handshake failure.");
		exit (1);
	}

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

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

	if (result < 0 || PR_GetError () != 0) {
		printf ("Write successful\n");
		exit (1);
	}

	return 0;
}

Reply via email to