#include #include #include #include #include #include #include #include #include #include #include #include #include unsigned int bufsize=4096; int stdinready() { struct timeval timeout; fd_set iofds; /* Set up timeout */ timeout.tv_sec = 1; timeout.tv_usec = 0; /* file descriptor bits */ FD_ZERO(&iofds); FD_SET(0, &iofds); return select(1, &iofds, (fd_set *)0, (fd_set *)0, &timeout); } void copyloop(int insock, int outsock) { fd_set iofds; fd_set c_iofds; int max_fd; /* Maximum numbered fd used */ unsigned long bytes; char buf[bufsize]; /* file descriptor bits */ FD_ZERO(&iofds); FD_SET(insock, &iofds); FD_SET(outsock, &iofds); if (insock > outsock) { max_fd = insock; } else { max_fd = outsock; } while (1) { (void) memcpy(&c_iofds, &iofds, sizeof(iofds)); if (select(max_fd + 1, &c_iofds, (fd_set *)0, (fd_set *)0, NULL) <= 0) { break; } if(FD_ISSET(insock, &c_iofds)) { if((bytes = read(insock, buf, sizeof(buf))) <= 0) break; if(write(outsock, buf, bytes) != bytes) break; } if(FD_ISSET(outsock, &c_iofds)) { if((bytes = read(outsock, buf, sizeof(buf))) <= 0) break; if(write(insock, buf, bytes) != bytes) break; } } shutdown(insock,0); shutdown(outsock,0); close(insock); close(outsock); return; } int main(int argc, char *argv[]) { char *sshd_addr; char *httpd_addr; char *target_addr; int sshd_port; int httpd_port; int target_port; struct sockaddr_in target; struct hostent *hp; int targetsock; #ifdef TRANSPROXY struct sockaddr_in client; int client_size = sizeof(client); struct sockaddr_in addr_out; getpeername(0, (struct sockaddr *) &client, &client_size); #endif if (argc <= 4) { fprintf(stderr, "Usage: muxsshssl ssh-addr ssh-port ssl-addr ssl-port\n"); exit(1); } sshd_addr = argv[1]; sshd_port = atol(argv[2]); httpd_addr = argv[3]; httpd_port = atol(argv[4]); /* Choose target port here */ if (stdinready()) { target_addr = sshd_addr; target_port = sshd_port; } else { target_addr = httpd_addr; target_port = httpd_port; } /* Set up target */ target.sin_family = AF_INET; target.sin_port = htons(target_port); if ((hp = gethostbyname(target_addr)) == NULL) { fprintf(stderr, "%s: host unknown.\n", target_addr); exit(1); } memcpy(&target.sin_addr, hp->h_addr, hp->h_length); if ((targetsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("target: socket"); exit(1); } #ifdef TRANSPROXY memcpy(&addr_out, &client, sizeof(struct sockaddr_in)); addr_out.sin_port = 0; if (bind(targetsock, (struct sockaddr *) &addr_out, sizeof(addr_out)) < 0) { perror("bind_addr: cannot bind to forced outgoing addr"); exit(1); } #endif if (connect(targetsock, (struct sockaddr *) &target, sizeof(target)) < 0) { perror("target: connect"); exit(1); } /* Just start copying - one side of the loop is stdin - 0 */ copyloop(0, targetsock); /* this should really never be reached */ exit(0); }