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