1/* NOCW */ 2/* demos/bio/saccept-conf.c */ 3 4/* 5 * A minimal program to serve an SSL connection. It uses blocking. It uses 6 * the SSL_CONF API with a configuration file. cc -I../../include saccept.c 7 * -L../.. -lssl -lcrypto -ldl 8 */ 9 10#include <stdio.h> 11#include <signal.h> 12#include <openssl/err.h> 13#include <openssl/ssl.h> 14#include <openssl/conf.h> 15 16int main(int argc, char *argv[]) 17{ 18 char *port = "*:4433"; 19 BIO *in = NULL; 20 BIO *ssl_bio, *tmp; 21 SSL_CTX *ctx; 22 SSL_CONF_CTX *cctx = NULL; 23 CONF *conf = NULL; 24 STACK_OF(CONF_VALUE) *sect = NULL; 25 CONF_VALUE *cnf; 26 long errline = -1; 27 char buf[512]; 28 int ret = 1, i; 29 30 SSL_load_error_strings(); 31 32 /* Add ciphers and message digests */ 33 OpenSSL_add_ssl_algorithms(); 34 35 conf = NCONF_new(NULL); 36 37 if (NCONF_load(conf, "accept.cnf", &errline) <= 0) { 38 if (errline <= 0) 39 fprintf(stderr, "Error processing config file\n"); 40 else 41 fprintf(stderr, "Error on line %ld\n", errline); 42 goto err; 43 } 44 45 sect = NCONF_get_section(conf, "default"); 46 47 if (sect == NULL) { 48 fprintf(stderr, "Error retrieving default section\n"); 49 goto err; 50 } 51 52 ctx = SSL_CTX_new(SSLv23_server_method()); 53 cctx = SSL_CONF_CTX_new(); 54 SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); 55 SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); 56 SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); 57 SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); 58 for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 59 int rv; 60 cnf = sk_CONF_VALUE_value(sect, i); 61 rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); 62 if (rv > 0) 63 continue; 64 if (rv != -2) { 65 fprintf(stderr, "Error processing %s = %s\n", 66 cnf->name, cnf->value); 67 ERR_print_errors_fp(stderr); 68 goto err; 69 } 70 if (!strcmp(cnf->name, "Port")) { 71 port = cnf->value; 72 } else { 73 fprintf(stderr, "Unknown configuration option %s\n", cnf->name); 74 goto err; 75 } 76 } 77 78 if (!SSL_CONF_CTX_finish(cctx)) { 79 fprintf(stderr, "Finish error\n"); 80 ERR_print_errors_fp(stderr); 81 goto err; 82 } 83 84 /* Setup server side SSL bio */ 85 ssl_bio = BIO_new_ssl(ctx, 0); 86 87 if ((in = BIO_new_accept(port)) == NULL) 88 goto err; 89 90 /* 91 * This means that when a new connection is accepted on 'in', The ssl_bio 92 * will be 'duplicated' and have the new socket BIO push into it. 93 * Basically it means the SSL BIO will be automatically setup 94 */ 95 BIO_set_accept_bios(in, ssl_bio); 96 97 again: 98 /* 99 * The first call will setup the accept socket, and the second will get a 100 * socket. In this loop, the first actual accept will occur in the 101 * BIO_read() function. 102 */ 103 104 if (BIO_do_accept(in) <= 0) 105 goto err; 106 107 for (;;) { 108 i = BIO_read(in, buf, 512); 109 if (i == 0) { 110 /* 111 * If we have finished, remove the underlying BIO stack so the 112 * next time we call any function for this BIO, it will attempt 113 * to do an accept 114 */ 115 printf("Done\n"); 116 tmp = BIO_pop(in); 117 BIO_free_all(tmp); 118 goto again; 119 } 120 if (i < 0) { 121 if (BIO_should_retry(in)) 122 continue; 123 goto err; 124 } 125 fwrite(buf, 1, i, stdout); 126 fflush(stdout); 127 } 128 129 ret = 0; 130 err: 131 if (ret) { 132 ERR_print_errors_fp(stderr); 133 } 134 if (in != NULL) 135 BIO_free(in); 136 exit(ret); 137 return (!ret); 138} 139