Path: blob/main/crypto/openssl/demos/bio/saccept.c
34869 views
/*1* Copyright 1998-2024 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*-10* A minimal program to serve an SSL connection.11* It uses blocking.12* saccept host:port13* host is the interface IP to use. If any interface, use *:port14* The default it *:443315*16* cc -I../../include saccept.c -L../.. -lssl -lcrypto -ldl17*/1819#include <stdio.h>20#include <signal.h>21#include <stdlib.h>22#include <openssl/err.h>23#include <openssl/ssl.h>2425#define CERT_FILE "server.pem"2627static volatile int done = 0;2829static void interrupt(int sig)30{31done = 1;32}3334static void sigsetup(void)35{36#if defined(OPENSSL_SYS_WINDOWS)37signal(SIGINT, interrupt);38#else39struct sigaction sa;4041/*42* Catch at most once, and don't restart the accept system call.43*/44sa.sa_flags = SA_RESETHAND;45sa.sa_handler = interrupt;46sigemptyset(&sa.sa_mask);47sigaction(SIGINT, &sa, NULL);48#endif49}5051int main(int argc, char *argv[])52{53char *port = NULL;54BIO *in = NULL;55BIO *ssl_bio, *tmp;56SSL_CTX *ctx;57char buf[512];58int ret = EXIT_FAILURE, i;5960if (argc <= 1)61port = "*:4433";62else63port = argv[1];6465ctx = SSL_CTX_new(TLS_server_method());66if (!SSL_CTX_use_certificate_chain_file(ctx, CERT_FILE))67goto err;68if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))69goto err;70if (!SSL_CTX_check_private_key(ctx))71goto err;7273/* Setup server side SSL bio */74ssl_bio = BIO_new_ssl(ctx, 0);7576if ((in = BIO_new_accept(port)) == NULL)77goto err;7879/*80* This means that when a new connection is accepted on 'in', The ssl_bio81* will be 'duplicated' and have the new socket BIO push into it.82* Basically it means the SSL BIO will be automatically setup83*/84BIO_set_accept_bios(in, ssl_bio);8586/* Arrange to leave server loop on interrupt */87sigsetup();8889again:90/*91* The first call will setup the accept socket, and the second will get a92* socket. In this loop, the first actual accept will occur in the93* BIO_read() function.94*/9596if (BIO_do_accept(in) <= 0)97goto err;9899while (!done) {100i = BIO_read(in, buf, 512);101if (i == 0) {102/*103* If we have finished, remove the underlying BIO stack so the104* next time we call any function for this BIO, it will attempt105* to do an accept106*/107printf("Done\n");108tmp = BIO_pop(in);109BIO_free_all(tmp);110goto again;111}112if (i < 0)113goto err;114fwrite(buf, 1, i, stdout);115fflush(stdout);116}117118ret = EXIT_SUCCESS;119err:120if (ret != EXIT_SUCCESS)121ERR_print_errors_fp(stderr);122BIO_free(in);123return ret;124}125126127