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} 245