X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fnc.c;h=63d8c5b19db9b70b8f16527ac4a3f6e8ed7b5104;hb=9bf9f1edbec05edbf566c3220835440e1b18fcc8;hp=eb6e17762fdc0f85ade75cd7013b6fe3e0dd0f30;hpb=24be980004598c2fa0a3e14ccdce0bc7b3039985;p=oweals%2Fbusybox.git diff --git a/networking/nc.c b/networking/nc.c index eb6e17762..63d8c5b19 100644 --- a/networking/nc.c +++ b/networking/nc.c @@ -26,13 +26,9 @@ */ -#warning This applet has moved to netkit-tiny. After BusyBox 0.49, this -#warning applet will be removed from BusyBox. All maintenance efforts -#warning should be done in the netkit-tiny source tree. - -#include "busybox.h" #include #include +#include #include #include @@ -42,35 +38,104 @@ #include #include #include +#include "busybox.h" + +#define GAPING_SECURITY_HOLE int nc_main(int argc, char **argv) { - int sfd; + int do_listen = 0, lport = 0, delay = 0, tmpfd, opt, sfd, x; char buf[BUFSIZ]; +#ifdef GAPING_SECURITY_HOLE + char * pr00gie = NULL; +#endif struct sockaddr_in address; struct hostent *hostinfo; fd_set readfds, testfds; - argc--; - argv++; - if (argc < 2 || **argv == '-') { - usage(nc_usage); + while ((opt = getopt(argc, argv, "lp:i:e:")) > 0) { + switch (opt) { + case 'l': + do_listen++; + break; + case 'p': + lport = atoi(optarg); + break; + case 'i': + delay = atoi(optarg); + break; +#ifdef GAPING_SECURITY_HOLE + case 'e': + pr00gie = optarg; + break; +#endif + default: + show_usage(); + } } +#ifdef GAPING_SECURITY_HOLE + if (pr00gie) { + /* won't need stdin */ + close (fileno(stdin)); + } +#endif /* GAPING_SECURITY_HOLE */ + + + if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc)) + show_usage(); + if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror_msg_and_die("socket"); + x = 1; + if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1) + perror_msg_and_die ("reuseaddr failed"); + address.sin_family = AF_INET; - if ((hostinfo = gethostbyname(*argv)) == NULL) - error_msg_and_die("cannot resolve %s\n", *argv); + if (lport != 0) { + memset(&address.sin_addr, 0, sizeof(address.sin_addr)); + address.sin_port = htons(lport); - address.sin_family = AF_INET; - address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; - address.sin_port = htons(atoi(*(++argv))); + if (bind(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) + perror_msg_and_die("bind"); + } + + if (do_listen) { + socklen_t addrlen = sizeof(address); + + if (listen(sfd, 1) < 0) + perror_msg_and_die("listen"); + + if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0) + perror_msg_and_die("accept"); + + close(sfd); + sfd = tmpfd; + } else { + hostinfo = xgethostbyname(argv[optind]); + + address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; + address.sin_port = htons(atoi(argv[optind+1])); + + if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) + perror_msg_and_die("connect"); + } + +#ifdef GAPING_SECURITY_HOLE + /* -e given? */ + if (pr00gie) { + dup2(sfd, 0); + close(sfd); + dup2 (0, 1); + dup2 (0, 2); + execl (pr00gie, pr00gie, NULL); + /* Don't print stuff or it will go over the wire.... */ + _exit(-1); + } +#endif /* GAPING_SECURITY_HOLE */ - if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) - perror_msg_and_die("connect"); FD_ZERO(&readfds); FD_SET(sfd, &readfds); @@ -103,6 +168,9 @@ int nc_main(int argc, char **argv) if (full_write(ofd, buf, nread) < 0) perror_msg_and_die("write"); + if (delay > 0) { + sleep(delay); + } } } }