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