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