server-conf.c 3.0 KB
Newer Older
1
/* NOCW */
D
Dr. Stephen Henson 已提交
2
/* demos/bio/saccept-conf.c */
3

D
Dr. Stephen Henson 已提交
4
/* A minimal program to serve an SSL connection.
5
 * It uses blocking.
D
Dr. Stephen Henson 已提交
6
 * It uses the SSL_CONF API with a configuration file.
7
 *
D
Dr. Stephen Henson 已提交
8
 * cc -I../../include saccept.c -L../.. -lssl -lcrypto -ldl
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
 */

#include <stdio.h>
#include <signal.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>

int main(int argc, char *argv[])
	{
	char *port = "*:4433";
	BIO *in=NULL;
	BIO *ssl_bio,*tmp;
	SSL_CTX *ctx;
	SSL_CONF_CTX *cctx = NULL;
	CONF *conf = NULL;
	STACK_OF(CONF_VALUE) *sect = NULL;
	CONF_VALUE *cnf;
	long errline = -1;
	char buf[512];
	int ret=1,i;

	SSL_load_error_strings();

	/* Add ciphers and message digests */
	OpenSSL_add_ssl_algorithms();

	conf = NCONF_new(NULL);

	if (NCONF_load(conf, "accept.cnf", &errline) <= 0)
		{
		if (errline <= 0)
			fprintf(stderr, "Error processing config file\n");
		else
			fprintf(stderr, "Error on line %ld\n", errline);
		goto err;
		}

	sect = NCONF_get_section(conf, "default");

	if (sect == NULL)
		{
		fprintf(stderr, "Error retrieving default section\n");
		goto err;
		}

	ctx=SSL_CTX_new(SSLv23_server_method());
	cctx = SSL_CONF_CTX_new();
	SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
	SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
	SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
	SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
	for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
		{
		int rv;
		cnf = sk_CONF_VALUE_value(sect, i);
		rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
		if (rv > 0)
			continue;
		if (rv != -2)
			{
			fprintf(stderr, "Error processing %s = %s\n",
						cnf->name, cnf->value);
			ERR_print_errors_fp(stderr);
			goto err;
			}
		if (!strcmp(cnf->name, "Port"))
			{
			port = cnf->value;
			}
		else
			{
			fprintf(stderr, "Unknown configuration option %s\n",
							cnf->name);
			goto err;
			}
		}

	if (!SSL_CONF_CTX_finish(cctx))
		{
		fprintf(stderr, "Finish error\n");
		ERR_print_errors_fp(stderr);
		goto err;
		}

	/* Setup server side SSL bio */
	ssl_bio=BIO_new_ssl(ctx,0);

	if ((in=BIO_new_accept(port)) == NULL) goto err;

D
Dr. Stephen Henson 已提交
99 100
	/* This means that when a new connection is accepted on 'in',
	 * The ssl_bio will be 'duplicated' and have the new socket
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
	 * BIO push into it.  Basically it means the SSL BIO will be
	 * automatically setup */
	BIO_set_accept_bios(in,ssl_bio);

again:
	/* The first call will setup the accept socket, and the second
	 * will get a socket.  In this loop, the first actual accept
	 * will occur in the BIO_read() function. */

	if (BIO_do_accept(in) <= 0) goto err;

	for (;;)
		{
		i=BIO_read(in,buf,512);
		if (i == 0)
			{
			/* If we have finished, remove the underlying
			 * BIO stack so the next time we call any function
			 * for this BIO, it will attempt to do an
			 * accept */
			printf("Done\n");
			tmp=BIO_pop(in);
			BIO_free_all(tmp);
			goto again;
			}
D
Dr. Stephen Henson 已提交
126 127 128 129 130 131
		if (i < 0)
			{
			if (BIO_should_retry(in))
				continue;
			goto err;
			}
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
		fwrite(buf,1,i,stdout);
		fflush(stdout);
		}

	ret=0;
err:
	if (ret)
		{
		ERR_print_errors_fp(stderr);
		}
	if (in != NULL) BIO_free(in);
	exit(ret);
	return(!ret);
	}