OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
test.c
Go to the documentation of this file.
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
24 test_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 
29 void
30 test_errflush(int child_p, char *errbuf, size_t num, void *apparg)
31 {
32  fputs(errbuf, stderr);
33 }
34 
35 
36 int
37 main(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  {
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  {
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 }