Thread: SSL Socket fork()

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    5

    SSL Socket fork()

    Hi,

    I've been trying to create an C SSL Socket listener. I've successfully been able to accept connections (take input, send a response, then disconnect). However, I am now trying to use fork() to allow for multiple simultaneous connections. My code is below: (any help figuring this out is appreciated)
    server.c
    Code:
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <resolv.h>
    #include <openssl/ssl.h>
    #include <openssl/err.h>
    #include "server.h"
    void initChild(int client, SSL_CTX* ctx);
    
    void error(const char *msg) {
    	perror(msg);
    	exit(1);
    }
    
    int main(int count, char *strings[])
    {   SSL_CTX *ctx;
        int server;
        char *portnum;
    	int pid;
        if ( count != 2 )
        {
            printf("Usage: %s <portnum>\n", strings[0]);
            exit(0);
        }
    	SSL_library_init();
        portnum = strings[1];
    	ctx = InitServerCTX();											/* initialize SSL */  
      	LoadCertificates(ctx, "keys/mycert.pem", "keys/server.key");	/* load certs */
        server = OpenListener(atoi(portnum));							/* create server socket */
    	while (1) {
    		struct sockaddr_in addr;
    	    int len = sizeof(addr);
            int client = accept(server, (struct sockaddr*)&addr, &len);		/* accept connection as usual */
    		
    		if(!(pid = fork())) {
    			// Child process
    			//close(server);
    			initChild(client, ctx);	
    			exit(0);
    		} else if(pid > 0) {
    			// Parent process
    		} else {
    			// Fork failed
    			//close(server);
    		}
    	}
    	close(server);
    	SSL_CTX_free(ctx);	
    
    	return 0;
    }
    void initChild(int client, SSL_CTX* ctx) {
    	printf("Doing some stuff");
    	SSL ........l;
    	ssl = SSL_new(ctx);         									/* get new SSL state with context */	
    	SSL_set_fd(ssl, client);										/* set connection socket to SSL state */
    	//sd = SSL_get_fd(ssl);							/* get socket connection */
        //SSL_free(ssl);									/* release SSL state */
        //close(sd);
    	//close(client);
        Servlet(ssl);
    
    }
    server.h
    Code:
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <resolv.h>
    #include <openssl/ssl.h>
    #include <openssl/err.h>
    
    #define FAIL    -1
    
    /*---------------------------------------------------------------------*/
    /*--- OpenListener - create server socket                           ---*/
    /*---------------------------------------------------------------------*/
    int OpenListener(int port)
    {   int sd;
        struct sockaddr_in addr;
    
        sd = socket(PF_INET, SOCK_STREAM, 0);
        bzero(&addr, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = INADDR_ANY;
        if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
        {
            perror("can't bind port");
            abort();
        }
        if ( listen(sd, 10) != 0 )
        {
            perror("Can't configure listening port");
            abort();
        }
        return sd;
    }
    
    /*---------------------------------------------------------------------*/
    /*--- InitServerCTX - initialize SSL server  and create context     ---*/
    /*---------------------------------------------------------------------*/
    SSL_CTX* InitServerCTX(void)
    {   SSL_METHOD *method;
        SSL_CTX *ctx;
    
        OpenSSL_add_all_algorithms();		/* load & register all cryptos, etc. */
        SSL_load_error_strings();			/* load all error messages */
        method = SSLv2_server_method();		/* create new server-method instance */
        ctx = SSL_CTX_new(method);			/* create new context from method */
        if ( ctx == NULL )
        {
            ERR_print_errors_fp(stderr);
            abort();
        }
        return ctx;
    }
    
    /*---------------------------------------------------------------------*/
    /*--- LoadCertificates - load from files.                           ---*/
    /*---------------------------------------------------------------------*/
    void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
    {
    	/* set the local certificate from CertFile */
        if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
        {
            ERR_print_errors_fp(stderr);
            abort();
        }
        /* set the private key from KeyFile (may be the same as CertFile) */
        if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
        {
            ERR_print_errors_fp(stderr);
            abort();
        }
        /* verify private key */
        if ( !SSL_CTX_check_private_key(ctx) )
        {
            fprintf(stderr, "Private key does not match the public certificate\n");
            abort();
        }
    }
    
    /*---------------------------------------------------------------------*/
    /*--- ShowCerts - print out certificates.                           ---*/
    /*---------------------------------------------------------------------*/
    void ShowCerts(SSL* ssl)
    {   X509 *cert;
        char *line;
    
        cert = SSL_get_peer_certificate(ssl);	/* Get certificates (if available) */
        if ( cert != NULL )
        {
            printf("Server certificates:\n");
            line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
            printf("Subject: %s\n", line);
            free(line);
            line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
            printf("Issuer: %s\n", line);
            free(line);
            X509_free(cert);
        }
        else
            printf("No certificates.\n");
    }
    
    /*---------------------------------------------------------------------*/
    /*--- Servlet - SSL servlet (contexts can be shared)                ---*/
    /*---------------------------------------------------------------------*/
    void Servlet(SSL* ssl)	/* Serve the connection -- threadable */
    {   char buf[1024];
        char reply[1024];
        int sd, bytes;
        const char* HTMLecho="<html><body><pre>The message \"<strong>%s</strong>\" has been received!</pre></body></html>\n\n";
    
        if ( SSL_accept(ssl) == FAIL )					/* do SSL-protocol accept */
            ERR_print_errors_fp(stderr);
        else
        {
            ShowCerts(ssl);								/* get any certificates */
            bytes = SSL_read(ssl, buf, sizeof(buf));	/* get request */
            if ( bytes > 0 )
            {
                buf[bytes] = 0;
                printf("Client msg: \"%s\"\n", buf);
                sprintf(reply, HTMLecho, buf);			/* construct reply */
                SSL_write(ssl, reply, strlen(reply));	/* send reply */
            }
            else
                ERR_print_errors_fp(stderr);
        }
        sd = SSL_get_fd(ssl);							/* get socket connection */
        SSL_free(ssl);									/* release SSL state */
        close(sd);										/* close connection */
    }

  2. #2
    Registered User
    Join Date
    Nov 2004
    Location
    USA
    Posts
    516
    What error are you getting?
    Code:
    >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The parent/child need to close ALL the descriptors they're not interested in.
    Child closes server, parent closes client.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Socket programming in C with socket.h
    By funzy in forum Networking/Device Communication
    Replies: 13
    Last Post: 08-29-2008, 04:12 AM
  2. y does it run fork twice
    By raja9911 in forum C Programming
    Replies: 3
    Last Post: 02-03-2006, 03:08 AM
  3. n00b doing a Socket operation on non-socket
    By Kinasz in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-25-2004, 03:29 AM
  4. fork() ???
    By Devil Panther in forum Linux Programming
    Replies: 7
    Last Post: 09-20-2003, 08:16 AM