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
server.hCode:#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); }
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 */ }



LinkBack URL
About LinkBacks


