Dead code cleanup: crypto/*.c, x509v3, demos
[openssl.git] / demos / easy_tls / test.c
1 /* test.c */
2 /* $Id: test.c,v 1.1 2001/09/17 19:06:59 bodo Exp $ */
3
4 #define L_PORT 9999
5 #define C_PORT 443
6
7 #include <arpa/inet.h>
8 #include <assert.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <sys/select.h>
17 #include <sys/socket.h>
18 #include <unistd.h>
19
20 #include "test.h"
21 #include "easy-tls.h"
22
23 void test_process_init(int fd, int client_p, void *apparg)
24 {
25     fprintf(stderr,
26             "test_process_init(fd = %d, client_p = %d, apparg = %p)\n", fd,
27             client_p, apparg);
28 }
29
30 void test_errflush(int child_p, char *errbuf, size_t num, void *apparg)
31 {
32     fputs(errbuf, stderr);
33 }
34
35 int main(int argc, char *argv[])
36 {
37     int s, fd, r;
38     FILE *conn_in;
39     FILE *conn_out;
40     char buf[256];
41     SSL_CTX *ctx;
42     int client_p = 0;
43     int port;
44     int tls = 0;
45     char infobuf[TLS_INFO_SIZE + 1];
46
47     if (argc > 1 && argv[1][0] == '-') {
48         fputs("Usage: test [port]                   -- server\n"
49               "       test num.num.num.num [port]   -- client\n", stderr);
50         exit(1);
51     }
52
53     if (argc > 1) {
54         if (strchr(argv[1], '.')) {
55             client_p = 1;
56         }
57     }
58
59     fputs(client_p ? "Client\n" : "Server\n", stderr);
60
61     {
62         struct tls_create_ctx_args a = tls_create_ctx_defaultargs();
63         a.client_p = client_p;
64         a.certificate_file = "cert.pem";
65         a.key_file = "cert.pem";
66         a.ca_file = "cacerts.pem";
67
68         ctx = tls_create_ctx(a, NULL);
69         if (ctx == NULL)
70             exit(1);
71     }
72
73     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
74     if (s == -1) {
75         perror("socket");
76         exit(1);
77     }
78
79     if (client_p) {
80         struct sockaddr_in addr;
81         size_t addr_len = sizeof addr;
82
83         addr.sin_family = AF_INET;
84         assert(argc > 1);
85         if (argc > 2)
86             sscanf(argv[2], "%d", &port);
87         else
88             port = C_PORT;
89         addr.sin_port = htons(port);
90         addr.sin_addr.s_addr = inet_addr(argv[1]);
91
92         r = connect(s, &addr, addr_len);
93         if (r != 0) {
94             perror("connect");
95             exit(1);
96         }
97         fd = s;
98         fprintf(stderr, "Connect (fd = %d).\n", fd);
99     } else {
100         /* server */
101         {
102             int i = 1;
103
104             r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof i);
105             if (r == -1) {
106                 perror("setsockopt");
107                 exit(1);
108             }
109         }
110
111         {
112             struct sockaddr_in addr;
113             size_t addr_len = sizeof addr;
114
115             if (argc > 1)
116                 sscanf(argv[1], "%d", &port);
117             else
118                 port = L_PORT;
119             addr.sin_family = AF_INET;
120             addr.sin_port = htons(port);
121             addr.sin_addr.s_addr = INADDR_ANY;
122
123             r = bind(s, &addr, addr_len);
124             if (r != 0) {
125                 perror("bind");
126                 exit(1);
127             }
128         }
129
130         r = listen(s, 1);
131         if (r == -1) {
132             perror("listen");
133             exit(1);
134         }
135
136         fprintf(stderr, "Listening at port %i.\n", port);
137
138         fd = accept(s, NULL, 0);
139         if (fd == -1) {
140             perror("accept");
141             exit(1);
142         }
143
144         fprintf(stderr, "Accept (fd = %d).\n", fd);
145     }
146
147     conn_in = fdopen(fd, "r");
148     if (conn_in == NULL) {
149         perror("fdopen");
150         exit(1);
151     }
152     conn_out = fdopen(fd, "w");
153     if (conn_out == NULL) {
154         perror("fdopen");
155         exit(1);
156     }
157
158     setvbuf(conn_in, NULL, _IOLBF, 256);
159     setvbuf(conn_out, NULL, _IOLBF, 256);
160
161     while (fgets(buf, sizeof buf, stdin) != NULL) {
162         if (buf[0] == 'W') {
163             fprintf(conn_out, "%.*s\r\n", (int)(strlen(buf + 1) - 1),
164                     buf + 1);
165             fprintf(stderr, ">>> %.*s\n", (int)(strlen(buf + 1) - 1),
166                     buf + 1);
167         } else if (buf[0] == 'C') {
168             fprintf(stderr, "Closing.\n");
169             fclose(conn_in);
170             fclose(conn_out);
171             exit(0);
172         } else if (buf[0] == 'R') {
173             int lines = 0;
174
175             sscanf(buf + 1, "%d", &lines);
176             do {
177                 if (fgets(buf, sizeof buf, conn_in) == NULL) {
178                     if (ferror(conn_in)) {
179                         fprintf(stderr, "ERROR\n");
180                         exit(1);
181                     }
182                     fprintf(stderr, "CLOSED\n");
183                     return 0;
184                 }
185                 fprintf(stderr, "<<< %s", buf);
186             } while (--lines > 0);
187         } else if (buf[0] == 'T') {
188             int infofd;
189
190             tls++;
191             {
192                 struct tls_start_proxy_args a = tls_start_proxy_defaultargs();
193                 a.fd = fd;
194                 a.client_p = client_p;
195                 a.ctx = ctx;
196                 a.infofd = &infofd;
197                 r = tls_start_proxy(a, NULL);
198             }
199             assert(r != 1);
200             if (r != 0) {
201                 fprintf(stderr, "tls_start_proxy failed: %d\n", r);
202                 switch (r) {
203                 case -1:
204                     fputs("socketpair", stderr);
205                     break;
206                 case 2:
207                     fputs("FD_SETSIZE exceeded", stderr);
208                     break;
209                 case -3:
210                     fputs("pipe", stderr);
211                     break;
212                 case -4:
213                     fputs("fork", stderr);
214                     break;
215                 case -5:
216                     fputs("dup2", stderr);
217                     break;
218                 default:
219                     fputs("?", stderr);
220                 }
221                 if (r < 0)
222                     perror("");
223                 else
224                     fputc('\n', stderr);
225                 exit(1);
226             }
227
228             r = read(infofd, infobuf, sizeof infobuf - 1);
229             if (r > 0) {
230                 const char *info = infobuf;
231                 const char *eol;
232
233                 infobuf[r] = '\0';
234                 while ((eol = strchr(info, '\n')) != NULL) {
235                     fprintf(stderr, "+++ `%.*s'\n", eol - info, info);
236                     info = eol + 1;
237                 }
238                 close(infofd);
239             }
240         } else {
241             fprintf(stderr, "W...  write line to network\n"
242                     "R[n]  read line (n lines) from network\n"
243                     "C     close\n"
244                     "T     start %sTLS proxy\n", tls ? "another " : "");
245         }
246     }
247     return 0;
248 }