test.c 4.9 KB

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