ref: 7be7d0681f567e97fd37f937c2e5e486d6d74eab
dir: /sys/src/ape/lib/openssl/demos/easy_tls/test.c/
/* test.c */ /* $Id: test.c,v 1.1 2001/09/17 19:06:59 bodo Exp $ */ #define L_PORT 9999 #define C_PORT 443 #include <arpa/inet.h> #include <assert.h> #include <errno.h> #include <fcntl.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/select.h> #include <sys/socket.h> #include <unistd.h> #include "test.h" #include "easy-tls.h" void test_process_init(int fd, int client_p, void *apparg) { fprintf(stderr, "test_process_init(fd = %d, client_p = %d, apparg = %p)\n", fd, client_p, apparg); } void test_errflush(int child_p, char *errbuf, size_t num, void *apparg) { fputs(errbuf, stderr); } int main(int argc, char *argv[]) { int s, fd, r; FILE *conn_in; FILE *conn_out; char buf[256]; SSL_CTX *ctx; int client_p = 0; int port; int tls = 0; char infobuf[TLS_INFO_SIZE + 1]; if (argc > 1 && argv[1][0] == '-') { fputs("Usage: test [port] -- server\n" " test num.num.num.num [port] -- client\n", stderr); exit(1); } if (argc > 1) { if (strchr(argv[1], '.')) { client_p = 1; } } fputs(client_p ? "Client\n" : "Server\n", stderr); { struct tls_create_ctx_args a = tls_create_ctx_defaultargs(); a.client_p = client_p; a.certificate_file = "cert.pem"; a.key_file = "cert.pem"; a.ca_file = "cacerts.pem"; ctx = tls_create_ctx(a, NULL); if (ctx == NULL) exit(1); } s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == -1) { perror("socket"); exit(1); } if (client_p) { struct sockaddr_in addr; size_t addr_len = sizeof addr; addr.sin_family = AF_INET; assert(argc > 1); if (argc > 2) sscanf(argv[2], "%d", &port); else port = C_PORT; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(argv[1]); r = connect(s, &addr, addr_len); if (r != 0) { perror("connect"); exit(1); } fd = s; fprintf(stderr, "Connect (fd = %d).\n", fd); } else { /* server */ { int i = 1; r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof i); if (r == -1) { perror("setsockopt"); exit(1); } } { struct sockaddr_in addr; size_t addr_len = sizeof addr; if (argc > 1) sscanf(argv[1], "%d", &port); else port = L_PORT; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; r = bind(s, &addr, addr_len); if (r != 0) { perror("bind"); exit(1); } } r = listen(s, 1); if (r == -1) { perror("listen"); exit(1); } fprintf(stderr, "Listening at port %i.\n", port); fd = accept(s, NULL, 0); if (fd == -1) { perror("accept"); exit(1); } fprintf(stderr, "Accept (fd = %d).\n", fd); } conn_in = fdopen(fd, "r"); if (conn_in == NULL) { perror("fdopen"); exit(1); } conn_out = fdopen(fd, "w"); if (conn_out == NULL) { perror("fdopen"); exit(1); } setvbuf(conn_in, NULL, _IOLBF, 256); setvbuf(conn_out, NULL, _IOLBF, 256); while (fgets(buf, sizeof buf, stdin) != NULL) { if (buf[0] == 'W') { fprintf(conn_out, "%.*s\r\n", (int)(strlen(buf + 1) - 1), buf + 1); fprintf(stderr, ">>> %.*s\n", (int)(strlen(buf + 1) - 1), buf + 1); } else if (buf[0] == 'C') { fprintf(stderr, "Closing.\n"); fclose(conn_in); fclose(conn_out); exit(0); } else if (buf[0] == 'R') { int lines = 0; sscanf(buf + 1, "%d", &lines); do { if (fgets(buf, sizeof buf, conn_in) == NULL) { if (ferror(conn_in)) { fprintf(stderr, "ERROR\n"); exit(1); } fprintf(stderr, "CLOSED\n"); return 0; } fprintf(stderr, "<<< %s", buf); } while (--lines > 0); } else if (buf[0] == 'T') { int infofd; tls++; { struct tls_start_proxy_args a = tls_start_proxy_defaultargs(); a.fd = fd; a.client_p = client_p; a.ctx = ctx; a.infofd = &infofd; r = tls_start_proxy(a, NULL); } assert(r != 1); if (r != 0) { fprintf(stderr, "tls_start_proxy failed: %d\n", r); switch (r) { case -1: fputs("socketpair", stderr); break; case 2: fputs("FD_SETSIZE exceeded", stderr); break; case -3: fputs("pipe", stderr); break; case -4: fputs("fork", stderr); break; case -5: fputs("dup2", stderr); break; default: fputs("?", stderr); } if (r < 0) perror(""); else fputc('\n', stderr); exit(1); } r = read(infofd, infobuf, sizeof infobuf - 1); if (r > 0) { const char *info = infobuf; const char *eol; infobuf[r] = '\0'; while ((eol = strchr(info, '\n')) != NULL) { fprintf(stderr, "+++ `%.*s'\n", eol - info, info); info = eol+1; } close (infofd); } } else { fprintf(stderr, "W... write line to network\n" "R[n] read line (n lines) from network\n" "C close\n" "T start %sTLS proxy\n", tls ? "another " : ""); } } return 0; }