]>
Commit | Line | Data |
---|---|---|
ebd14bfc | 1 | /* NOCW */ |
f3efeaad | 2 | /* demos/bio/server-arg.c */ |
ebd14bfc | 3 | |
0f113f3e MC |
4 | /* |
5 | * A minimal program to serve an SSL connection. It uses blocking. It use the | |
6 | * SSL_CONF API with the command line. cc -I../../include server-arg.c | |
7 | * -L../.. -lssl -lcrypto -ldl | |
ebd14bfc DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
11 | #include <signal.h> | |
12 | #include <openssl/err.h> | |
13 | #include <openssl/ssl.h> | |
14 | ||
ebd14bfc | 15 | int main(int argc, char *argv[]) |
0f113f3e MC |
16 | { |
17 | char *port = "*:4433"; | |
18 | BIO *ssl_bio, *tmp; | |
19 | SSL_CTX *ctx; | |
20 | SSL_CONF_CTX *cctx; | |
21 | char buf[512]; | |
22 | BIO *in = NULL; | |
23 | int ret = 1, i; | |
24 | char **args = argv + 1; | |
25 | int nargs = argc - 1; | |
26 | ||
27 | SSL_load_error_strings(); | |
28 | ||
29 | /* Add ciphers and message digests */ | |
30 | OpenSSL_add_ssl_algorithms(); | |
31 | ||
32 | ctx = SSL_CTX_new(SSLv23_server_method()); | |
33 | ||
34 | cctx = SSL_CONF_CTX_new(); | |
35 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); | |
36 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); | |
37 | SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); | |
38 | while (*args && **args == '-') { | |
39 | int rv; | |
40 | /* Parse standard arguments */ | |
41 | rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); | |
42 | if (rv == -3) { | |
43 | fprintf(stderr, "Missing argument for %s\n", *args); | |
44 | goto err; | |
45 | } | |
46 | if (rv < 0) { | |
47 | fprintf(stderr, "Error in command %s\n", *args); | |
48 | ERR_print_errors_fp(stderr); | |
49 | goto err; | |
50 | } | |
51 | /* If rv > 0 we processed something so proceed to next arg */ | |
52 | if (rv > 0) | |
53 | continue; | |
54 | /* Otherwise application specific argument processing */ | |
55 | if (!strcmp(*args, "-port")) { | |
56 | port = args[1]; | |
57 | if (port == NULL) { | |
58 | fprintf(stderr, "Missing -port argument\n"); | |
59 | goto err; | |
60 | } | |
61 | args += 2; | |
62 | nargs -= 2; | |
63 | continue; | |
64 | } else { | |
65 | fprintf(stderr, "Unknown argument %s\n", *args); | |
66 | goto err; | |
67 | } | |
68 | } | |
69 | ||
70 | if (!SSL_CONF_CTX_finish(cctx)) { | |
71 | fprintf(stderr, "Finish error\n"); | |
72 | ERR_print_errors_fp(stderr); | |
73 | goto err; | |
74 | } | |
0f78819c | 75 | #if 0 |
0f113f3e MC |
76 | /* |
77 | * Demo of how to iterate over all certificates in an SSL_CTX structure. | |
78 | */ | |
79 | { | |
80 | X509 *x; | |
81 | int rv; | |
82 | rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); | |
83 | while (rv) { | |
84 | X509 *x = SSL_CTX_get0_certificate(ctx); | |
85 | X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, | |
86 | XN_FLAG_ONELINE); | |
87 | printf("\n"); | |
88 | rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); | |
89 | } | |
90 | fflush(stdout); | |
91 | } | |
0f78819c | 92 | #endif |
0f113f3e MC |
93 | /* Setup server side SSL bio */ |
94 | ssl_bio = BIO_new_ssl(ctx, 0); | |
95 | ||
96 | if ((in = BIO_new_accept(port)) == NULL) | |
97 | goto err; | |
98 | ||
99 | /* | |
100 | * This means that when a new connection is accepted on 'in', The ssl_bio | |
101 | * will be 'duplicated' and have the new socket BIO push into it. | |
102 | * Basically it means the SSL BIO will be automatically setup | |
103 | */ | |
104 | BIO_set_accept_bios(in, ssl_bio); | |
105 | ||
106 | again: | |
107 | /* | |
108 | * The first call will setup the accept socket, and the second will get a | |
109 | * socket. In this loop, the first actual accept will occur in the | |
110 | * BIO_read() function. | |
111 | */ | |
112 | ||
113 | if (BIO_do_accept(in) <= 0) | |
114 | goto err; | |
115 | ||
116 | for (;;) { | |
117 | i = BIO_read(in, buf, 512); | |
118 | if (i == 0) { | |
119 | /* | |
120 | * If we have finished, remove the underlying BIO stack so the | |
121 | * next time we call any function for this BIO, it will attempt | |
122 | * to do an accept | |
123 | */ | |
124 | printf("Done\n"); | |
125 | tmp = BIO_pop(in); | |
126 | BIO_free_all(tmp); | |
127 | goto again; | |
128 | } | |
129 | if (i < 0) | |
130 | goto err; | |
131 | fwrite(buf, 1, i, stdout); | |
132 | fflush(stdout); | |
133 | } | |
134 | ||
135 | ret = 0; | |
136 | err: | |
137 | if (ret) { | |
138 | ERR_print_errors_fp(stderr); | |
139 | } | |
140 | if (in != NULL) | |
141 | BIO_free(in); | |
142 | exit(ret); | |
143 | return (!ret); | |
144 | } |