X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fnc.c;h=4888ccceb389145c624a7dfdd48d5166cfa821c2;hb=fe538ba5d68391562b23d9d0902b4219b6329cad;hp=e40d4b459491fd307b6b456f14dcb05d44926509;hpb=cbe31dace5fb24304694d399b9eb267fbe752516;p=oweals%2Fbusybox.git diff --git a/networking/nc.c b/networking/nc.c index e40d4b459..4888ccceb 100644 --- a/networking/nc.c +++ b/networking/nc.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -39,17 +40,22 @@ #include #include "busybox.h" +#define GAPING_SECURITY_HOLE + int nc_main(int argc, char **argv) { - int do_listen = 0, lport = 0, tmpfd, opt, 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; - while ((opt = getopt(argc, argv, "lp:")) > 0) { + while ((opt = getopt(argc, argv, "lp:i:e:")) > 0) { switch (opt) { case 'l': do_listen++; @@ -57,17 +63,35 @@ int nc_main(int argc, char **argv) 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(); + bb_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(); + bb_show_usage(); if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - perror_msg_and_die("socket"); - + bb_perror_msg_and_die("socket"); + x = 1; + if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1) + bb_perror_msg_and_die ("reuseaddr failed"); address.sin_family = AF_INET; if (lport != 0) { @@ -75,28 +99,43 @@ int nc_main(int argc, char **argv) address.sin_port = htons(lport); if (bind(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) - perror_msg_and_die("bind"); + bb_perror_msg_and_die("bind"); } if (do_listen) { + socklen_t addrlen = sizeof(address); + if (listen(sfd, 1) < 0) - perror_msg_and_die("listen"); + bb_perror_msg_and_die("listen"); - if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &opt)) < 0) - perror_msg_and_die("accept"); + if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0) + bb_perror_msg_and_die("accept"); close(sfd); sfd = tmpfd; } else { - if ((hostinfo = gethostbyname(argv[optind])) == NULL) - error_msg_and_die("cannot resolve %s\n", argv[optind]); + 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"); + bb_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 */ + FD_ZERO(&readfds); FD_SET(sfd, &readfds); @@ -110,12 +149,12 @@ int nc_main(int argc, char **argv) testfds = readfds; if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) - perror_msg_and_die("select"); + bb_perror_msg_and_die("select"); for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) - perror_msg_and_die("read"); + bb_perror_msg_and_die("read"); if (fd == sfd) { if (nread == 0) @@ -127,8 +166,11 @@ int nc_main(int argc, char **argv) ofd = sfd; } - if (full_write(ofd, buf, nread) < 0) - perror_msg_and_die("write"); + if (bb_full_write(ofd, buf, nread) < 0) + bb_perror_msg_and_die("write"); + if (delay > 0) { + sleep(delay); + } } } }