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