test.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 test_process_init(int fd, int client_p, void *apparg)
  20. {
  21. fprintf(stderr,
  22. "test_process_init(fd = %d, client_p = %d, apparg = %p)\n", fd,
  23. client_p, apparg);
  24. }
  25. void test_errflush(int child_p, char *errbuf, size_t num, void *apparg)
  26. {
  27. fputs(errbuf, stderr);
  28. }
  29. int main(int argc, char *argv[])
  30. {
  31. int s, fd, r;
  32. FILE *conn_in;
  33. FILE *conn_out;
  34. char buf[256];
  35. SSL_CTX *ctx;
  36. int client_p = 0;
  37. int port;
  38. int tls = 0;
  39. char infobuf[TLS_INFO_SIZE + 1];
  40. if (argc > 1 && argv[1][0] == '-') {
  41. fputs("Usage: test [port] -- server\n"
  42. " test num.num.num.num [port] -- client\n", stderr);
  43. exit(1);
  44. }
  45. if (argc > 1) {
  46. if (strchr(argv[1], '.')) {
  47. client_p = 1;
  48. }
  49. }
  50. fputs(client_p ? "Client\n" : "Server\n", stderr);
  51. {
  52. struct tls_create_ctx_args a = tls_create_ctx_defaultargs();
  53. a.client_p = client_p;
  54. a.certificate_file = "cert.pem";
  55. a.key_file = "cert.pem";
  56. a.ca_file = "cacerts.pem";
  57. ctx = tls_create_ctx(a, NULL);
  58. if (ctx == NULL)
  59. exit(1);
  60. }
  61. s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  62. if (s == -1) {
  63. perror("socket");
  64. exit(1);
  65. }
  66. if (client_p) {
  67. struct sockaddr_in addr;
  68. size_t addr_len = sizeof addr;
  69. addr.sin_family = AF_INET;
  70. assert(argc > 1);
  71. if (argc > 2)
  72. sscanf(argv[2], "%d", &port);
  73. else
  74. port = C_PORT;
  75. addr.sin_port = htons(port);
  76. addr.sin_addr.s_addr = inet_addr(argv[1]);
  77. r = connect(s, &addr, addr_len);
  78. if (r != 0) {
  79. perror("connect");
  80. exit(1);
  81. }
  82. fd = s;
  83. fprintf(stderr, "Connect (fd = %d).\n", fd);
  84. } else {
  85. /* server */
  86. {
  87. int i = 1;
  88. r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof i);
  89. if (r == -1) {
  90. perror("setsockopt");
  91. exit(1);
  92. }
  93. }
  94. {
  95. struct sockaddr_in addr;
  96. size_t addr_len = sizeof addr;
  97. if (argc > 1)
  98. sscanf(argv[1], "%d", &port);
  99. else
  100. port = L_PORT;
  101. addr.sin_family = AF_INET;
  102. addr.sin_port = htons(port);
  103. addr.sin_addr.s_addr = INADDR_ANY;
  104. r = bind(s, &addr, addr_len);
  105. if (r != 0) {
  106. perror("bind");
  107. exit(1);
  108. }
  109. }
  110. r = listen(s, 1);
  111. if (r == -1) {
  112. perror("listen");
  113. exit(1);
  114. }
  115. fprintf(stderr, "Listening at port %i.\n", port);
  116. fd = accept(s, NULL, 0);
  117. if (fd == -1) {
  118. perror("accept");
  119. exit(1);
  120. }
  121. fprintf(stderr, "Accept (fd = %d).\n", fd);
  122. }
  123. conn_in = fdopen(fd, "r");
  124. if (conn_in == NULL) {
  125. perror("fdopen");
  126. exit(1);
  127. }
  128. conn_out = fdopen(fd, "w");
  129. if (conn_out == NULL) {
  130. perror("fdopen");
  131. exit(1);
  132. }
  133. setvbuf(conn_in, NULL, _IOLBF, 256);
  134. setvbuf(conn_out, NULL, _IOLBF, 256);
  135. while (fgets(buf, sizeof buf, stdin) != NULL) {
  136. if (buf[0] == 'W') {
  137. fprintf(conn_out, "%.*s\r\n", (int)(strlen(buf + 1) - 1),
  138. buf + 1);
  139. fprintf(stderr, ">>> %.*s\n", (int)(strlen(buf + 1) - 1),
  140. 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);
  177. break;
  178. case 2:
  179. fputs("FD_SETSIZE exceeded", stderr);
  180. break;
  181. case -3:
  182. fputs("pipe", stderr);
  183. break;
  184. case -4:
  185. fputs("fork", stderr);
  186. break;
  187. case -5:
  188. fputs("dup2", stderr);
  189. break;
  190. default:
  191. fputs("?", stderr);
  192. }
  193. if (r < 0)
  194. perror("");
  195. else
  196. fputc('\n', stderr);
  197. exit(1);
  198. }
  199. r = read(infofd, infobuf, sizeof infobuf - 1);
  200. if (r > 0) {
  201. const char *info = infobuf;
  202. const char *eol;
  203. infobuf[r] = '\0';
  204. while ((eol = strchr(info, '\n')) != NULL) {
  205. fprintf(stderr, "+++ `%.*s'\n", eol - info, info);
  206. info = eol + 1;
  207. }
  208. close(infofd);
  209. }
  210. } else {
  211. fprintf(stderr, "W... write line to network\n"
  212. "R[n] read line (n lines) from network\n"
  213. "C close\n"
  214. "T start %sTLS proxy\n", tls ? "another " : "");
  215. }
  216. }
  217. return 0;
  218. }