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