Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
client.c File Reference
#include <stdio.h>
#include <string.h>
#include "prerror.h"
#include "pk11func.h"
#include "secitem.h"
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include "nspr.h"
#include "plgetopt.h"
#include "prio.h"
#include "prnetdb.h"
#include "nss.h"
#include "sslsample.h"

Go to the source code of this file.

Defines

#define RD_BUF_SIZE   (60 * 1024)

Functions

static void Usage (const char *progName)
PRFileDescsetupSSLSocket (PRNetAddr *addr)
SECStatus handle_connection (PRFileDesc *sslSocket, int connection)
SECStatus do_connects (void *a, int connection)
void client_main (unsigned short port, int connections, const char *hostName)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

int ssl2CipherSuites []
int ssl3CipherSuites []
GlobalThreadMgr threadMGR
char * certNickname = NULL
char * hostName = NULL
char * password = NULL
unsigned short port = 0
const char requestString [] = {"GET /testfile HTTP/1.0\r\n\r\n" }

Define Documentation

#define RD_BUF_SIZE   (60 * 1024)

Definition at line 68 of file client.c.


Function Documentation

void client_main ( unsigned short  port,
int  connections,
const char *  hostName 
)

Definition at line 331 of file client.c.

{
       int                  i;
       SECStatus     secStatus;
       PRStatus    prStatus;
       PRInt32     rv;
       PRNetAddr     addr;
       PRHostEnt   hostEntry;
       char        buffer[256];

       /* Setup network connection. */
       prStatus = PR_GetHostByName(hostName, buffer, 256, &hostEntry);
       if (prStatus != PR_SUCCESS) {
              exitErr("PR_GetHostByName");
       }

       rv = PR_EnumerateHostEnt(0, &hostEntry, port, &addr);
       if (rv < 0) {
              exitErr("PR_EnumerateHostEnt");
       }

       secStatus = launch_thread(&threadMGR, do_connects, &addr, 1);
       if (secStatus != SECSuccess) {
              exitErr("launch_thread");
       }

       if (connections > 1) {
              /* wait for the first connection to terminate, then launch the rest. */
              reap_threads(&threadMGR);
              /* Start up the connections */
              for (i = 2; i <= connections; ++i) {
                     secStatus = launch_thread(&threadMGR, do_connects, &addr, i);
                     if (secStatus != SECSuccess) {
                            errWarn("launch_thread");
                     }
              }
       }

       reap_threads(&threadMGR);
       destroy_thread_data(&threadMGR);
}

Here is the call graph for this function:

SECStatus do_connects ( void a,
int  connection 
)

Definition at line 253 of file client.c.

{
       PRNetAddr  *addr = (PRNetAddr *)a;
       PRFileDesc *sslSocket;
       PRHostEnt   hostEntry;
       char        buffer[PR_NETDB_BUF_SIZE];
       PRStatus    prStatus;
       PRIntn      hostenum;
       SECStatus   secStatus;

       /* Set up SSL secure socket. */
       sslSocket = setupSSLSocket(addr);
       if (sslSocket == NULL) {
              errWarn("setupSSLSocket");
              return SECFailure;
       }

       secStatus = SSL_SetPKCS11PinArg(sslSocket, password);
       if (secStatus != SECSuccess) {
              errWarn("SSL_SetPKCS11PinArg");
              return secStatus;
       }

       secStatus = SSL_SetURL(sslSocket, hostName);
       if (secStatus != SECSuccess) {
              errWarn("SSL_SetURL");
              return secStatus;
       }

       /* Prepare and setup network connection. */
       prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry);
       if (prStatus != PR_SUCCESS) {
              errWarn("PR_GetHostByName");
              return SECFailure;
       }

       hostenum = PR_EnumerateHostEnt(0, &hostEntry, port, addr);
       if (hostenum == -1) {
              errWarn("PR_EnumerateHostEnt");
              return SECFailure;
       }

       prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
       if (prStatus != PR_SUCCESS) {
              errWarn("PR_Connect");
              return SECFailure;
       }

       /* Established SSL connection, ready to send data. */
#if 0
       secStatus = SSL_ForceHandshake(sslSocket);
       if (secStatus != SECSuccess) {
              errWarn("SSL_ForceHandshake");
              return secStatus;
       }
#endif

       secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
       if (secStatus != SECSuccess) {
              errWarn("SSL_ResetHandshake");
              prStatus = PR_Close(sslSocket);
              if (prStatus != PR_SUCCESS) {
                     errWarn("PR_Close");
              }
              return secStatus;
       }

       secStatus = handle_connection(sslSocket, connection);
       if (secStatus != SECSuccess) {
              errWarn("handle_connection");
              return secStatus;
       }

       PR_Close(sslSocket);
       return SECSuccess;
}

Here is the call graph for this function:

SECStatus handle_connection ( PRFileDesc sslSocket,
int  connection 
)

Definition at line 197 of file client.c.

{
       int         countRead = 0;
       PRInt32  numBytes;
       char    *readBuffer;

       readBuffer = PORT_Alloc(RD_BUF_SIZE);
       if (!readBuffer) {
              exitErr("PORT_Alloc");
       }

       /* compose the http request here. */

       numBytes = PR_Write(sslSocket, requestString, strlen(requestString));
       if (numBytes <= 0) {
              errWarn("PR_Write");
              PR_Free(readBuffer);
              readBuffer = NULL;
              return SECFailure;
       }

       /* read until EOF */
       while (PR_TRUE) {
              numBytes = PR_Read(sslSocket, readBuffer, RD_BUF_SIZE);
              if (numBytes == 0) {
                     break; /* EOF */
              }
              if (numBytes < 0) {
                     errWarn("PR_Read");
                     break;
              }
              countRead += numBytes;
              fprintf(stderr, "***** Connection %d read %d bytes (%d total).\n", 
                     connection, numBytes, countRead );
              readBuffer[numBytes] = '\0';
              fprintf(stderr, "************\n%s\n************\n", readBuffer);
       }

       printSecurityInfo(sslSocket);
       
       PR_Free(readBuffer);
       readBuffer = NULL;

       /* Caller closes the socket. */

       fprintf(stderr, 
               "***** Connection %d read %d bytes total.\n", 
               connection, countRead);

       return SECSuccess;   /* success */
}

Here is the call graph for this function:

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 376 of file client.c.

{
       char *               certDir      = ".";
       char *               progName     = NULL;
       int                                 connections  = 1;
       char *               cipherString = NULL;
       SECStatus            secStatus;
       PLOptState *         optstate;
       PLOptStatus          status;

       /* Call the NSPR initialization routines */
       PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

       progName = PL_strdup(argv[0]);

       hostName = NULL;
       optstate = PL_CreateOptState(argc, argv, "C:c:d:n:p:w:");
       while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
              switch(optstate->option) {
              case 'C' : cipherString = PL_strdup(optstate->value); break;
              case 'c' : connections = PORT_Atoi(optstate->value);  break;
              case 'd' : certDir = PL_strdup(optstate->value);      break;
              case 'n' : certNickname = PL_strdup(optstate->value); break;
              case 'p' : port = PORT_Atoi(optstate->value);         break;
              case 'w' : password = PL_strdup(optstate->value);     break;
              case '\0': hostName = PL_strdup(optstate->value);     break;
              default  : Usage(progName);
              }
       }

       if (port == 0 || hostName == NULL)
              Usage(progName);

       if (certDir == NULL) {
              certDir = PR_smprintf("%s/.netscape", getenv("HOME"));
       }

       /* Set our password function callback. */
       PK11_SetPasswordFunc(myPasswd);

       /* Initialize the NSS libraries. */
       secStatus = NSS_Init(certDir);
       if (secStatus != SECSuccess) {
              exitErr("NSS_Init");
       }

       /* All cipher suites except RSA_NULL_MD5 are enabled by Domestic Policy. */
       NSS_SetDomesticPolicy();
       SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);

       /* all the SSL2 and SSL3 cipher suites are enabled by default. */
       if (cipherString) {
           int ndx;

           /* disable all the ciphers, then enable the ones we want. */
           disableAllSSLCiphers();

           while (0 != (ndx = *cipherString++)) {
              int *cptr;
              int  cipher;

              if (! isalpha(ndx))
                  Usage(progName);
              cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
              for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
                  /* do nothing */;
              if (cipher) {
                  SSL_CipherPrefSetDefault(cipher, PR_TRUE);
              }
           }
       }

       client_main(port, connections, hostName);

       if (NSS_Shutdown() != SECSuccess) {
            exit(1);
        }
       PR_Cleanup();
       return 0;
}

Here is the call graph for this function:

Definition at line 90 of file client.c.

{
       PRFileDesc         *tcpSocket;
       PRFileDesc         *sslSocket;
       PRSocketOptionData   socketOption;
       PRStatus            prStatus;
       SECStatus           secStatus;

#if 0
retry:
#endif

       tcpSocket = PR_NewTCPSocket();
       if (tcpSocket == NULL) {
              errWarn("PR_NewTCPSocket");
       }

       /* Make the socket blocking. */
       socketOption.option              = PR_SockOpt_Nonblocking;
       socketOption.value.non_blocking = PR_FALSE;

       prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
       if (prStatus != PR_SUCCESS) {
              errWarn("PR_SetSocketOption");
              goto loser;
       } 

#if 0
       /* Verify that a connection can be made to the socket. */
       prStatus = PR_Connect(tcpSocket, addr, PR_INTERVAL_NO_TIMEOUT);
       if (prStatus != PR_SUCCESS) {
              PRErrorCode err = PR_GetError();
              if (err == PR_CONNECT_REFUSED_ERROR) {
                     PR_Close(tcpSocket);
                     PR_Sleep(PR_MillisecondsToInterval(10));
                     fprintf(stderr, "Connection to port refused, retrying.\n");
                     goto retry;
              }
              errWarn("PR_Connect");
              goto loser;
       }
#endif

       /* Import the socket into the SSL layer. */
       sslSocket = SSL_ImportFD(NULL, tcpSocket);
       if (!sslSocket) {
              errWarn("SSL_ImportFD");
              goto loser;
       }

       /* Set configuration options. */
       secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
       if (secStatus != SECSuccess) {
              errWarn("SSL_OptionSet:SSL_SECURITY");
              goto loser;
       }

       secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
       if (secStatus != SECSuccess) {
              errWarn("SSL_OptionSet:SSL_HANDSHAKE_AS_CLIENT");
              goto loser;
       }

       /* Set SSL callback routines. */
       secStatus = SSL_GetClientAuthDataHook(sslSocket,
                                 (SSLGetClientAuthData)myGetClientAuthData,
                                 (void *)certNickname);
       if (secStatus != SECSuccess) {
              errWarn("SSL_GetClientAuthDataHook");
              goto loser;
       }

       secStatus = SSL_AuthCertificateHook(sslSocket,
                                          (SSLAuthCertificate)myAuthCertificate,
                                       (void *)CERT_GetDefaultCertDB());
       if (secStatus != SECSuccess) {
              errWarn("SSL_AuthCertificateHook");
              goto loser;
       }

       secStatus = SSL_BadCertHook(sslSocket, 
                                  (SSLBadCertHandler)myBadCertHandler, NULL);
       if (secStatus != SECSuccess) {
              errWarn("SSL_BadCertHook");
              goto loser;
       }

       secStatus = SSL_HandshakeCallback(sslSocket, 
                                        (SSLHandshakeCallback)myHandshakeCallback,
                                        NULL);
       if (secStatus != SECSuccess) {
              errWarn("SSL_HandshakeCallback");
              goto loser;
       }

       return sslSocket;

loser:

       PR_Close(tcpSocket);
       return NULL;
}

Here is the call graph for this function:

static void Usage ( const char *  progName) [static]

Definition at line 80 of file client.c.

{
       fprintf(stderr, 
         "Usage: %s [-n rsa_nickname] [-p port] [-d dbdir] [-c connections]\n"
         "          [-w dbpasswd] [-C cipher(s)] hostname\n",
       progName);
       exit(1);
}

Here is the call graph for this function:


Variable Documentation

char* certNickname = NULL

Definition at line 74 of file client.c.

char* hostName = NULL

Definition at line 75 of file client.c.

char* password = NULL

Definition at line 76 of file client.c.

unsigned short port = 0

Definition at line 77 of file client.c.

const char requestString[] = {"GET /testfile HTTP/1.0\r\n\r\n" }

Definition at line 194 of file client.c.

Definition at line 104 of file selfserv.c.

Definition at line 114 of file selfserv.c.

Definition at line 73 of file client.c.