Nmap Development mailing list archives
Re: [PATCH] [Ncat] Fix EOF handling
From: bensonk () acm wwu edu
Date: Sat, 18 Apr 2009 20:21:47 -0700
The standard netcat behavior as defined by the canonical implementation by hobbit explicitly does not halt on EOF. I would recommend reversing the option, and instead providing an option like "-q N" in gentoo's netcat. The "-q N" option means "after EOF, exit after N seconds". Benson On Sat, Apr 18, 2009 at 08:10:23PM +0200, Daniel Roethlisberger wrote:
Ncat currently doesn't handle EOF events in a very intuitive way. Usability for scripting mainly depends on the ability to pipe into and out of Ncat: me@server $ ncat -l 1234 | tar xvf - me@client $ tar cvf - somedir | ncat server 1234 Currently, this does not work as expected, neither in the client nor in the server. In connect mode, EOF on standard input does not cause Ncat to exit. `cat file | ncat somewhere 1234' will keep running forever until Ncat receives a SIGINT. To be suitable for scripting, Ncat must exit after EOF on stdin. In listen mode, closing the TCP connection on the client side does not cause Ncat to flush stdout and exit, because Ncat is waiting for other connections. SIGINT does not help here, because Ncat will not write the remaining buffered bytes to stdout in that case, so a received file will have some missing bytes at the end. Cince this behaviour can be considered a feature, the attached patch adds a `-k' option, modelled after the *BSD nc(1) option of the same name. `-l -k' gives current behaviour, while just `-l' gives the expected, scriptable single-shot behaviour which is default for all netcat variants I am aware of (which is why I'd propose to make it the default). The attached patches fix EOF handling in both connect and listen mode as I'd expect Ncat to handle EOF. Comments? -- Daniel Roethlisberger http://daniel.roe.ch/
Index: ncat/ncat_connect.c =================================================================== --- ncat/ncat_connect.c (revision 12996) +++ ncat/ncat_connect.c (working copy) @@ -250,11 +250,9 @@ } /* end switch */ } else if (status == NSE_STATUS_EOF) { - /* Close up, got EOF from network side */ - if (nsi == cs->sock_nsi) { - nsi_delete(cs->stdin_nsi, NSOCK_PENDING_NOTIFY); - nsi_delete(cs->sock_nsi, NSOCK_PENDING_NOTIFY); - } + /* Close up, got EOF either on network side or on standard input. */ + nsi_delete(cs->stdin_nsi, NSOCK_PENDING_NOTIFY); + nsi_delete(cs->sock_nsi, NSOCK_PENDING_NOTIFY); } else if (status == NSE_STATUS_ERROR) { if (socket_errno() == EINPROGRESS) /* XXX: this is weird. errno always seems to be incorrect on ret from nsock. */
Index: ncat/ncat_core.h =================================================================== --- ncat/ncat_core.h (revision 12996) +++ ncat/ncat_core.h (working copy) @@ -21,6 +21,7 @@ int af; int broker; int listen; + int keepopen; int sendonly; int recvonly; int telnet; Index: ncat/ncat_listen.c =================================================================== --- ncat/ncat_listen.c (revision 12996) +++ ncat/ncat_listen.c (working copy) @@ -33,7 +33,7 @@ static void handle_connection(void); static void read_stdin(void); -static void read_socket(int recv_fd); +static int read_socket(int recv_fd); /* reap child processes */ static void sig_chld(int signo) @@ -114,7 +114,8 @@ read_stdin(); } else { /* Read from a client and write to stdout. */ - read_socket(i); + if (!read_socket(i) && !o.keepopen) + return 0; } fds_ready--; @@ -242,8 +243,9 @@ broadcast(&fds, &fdlist, buf, nbytes); } -/* Read from a client socket and write to stdout. */ -void read_socket(int recv_fd) +/* Read from a client socket and write to stdout. + * Returns zero if connection has been closed, non-zero otherwise. */ +int read_socket(int recv_fd) { char buf[DEFAULT_TCP_BUF_LEN]; struct fdinfo *fdn = get_fdinfo(&fdlist, recv_fd); @@ -279,7 +281,7 @@ if (conn_count == 0) FD_CLR(STDIN_FILENO, &master); - return; + return 0; } if(o.linedelay) @@ -301,6 +303,7 @@ if (o.ssl && fdn->ssl && SSL_pending(fdn->ssl)) goto readagain; #endif + return 1; } /* This is sufficiently different from the TCP code (wrt SSL, etc) that it Index: ncat/ncat_main.c =================================================================== --- ncat/ncat_main.c (revision 12996) +++ ncat/ncat_main.c (working copy) @@ -153,6 +153,7 @@ {"help", no_argument, NULL, 'h'}, {"delay", required_argument, NULL, 'd'}, {"listen", no_argument, NULL, 'l'}, + {"keep-open", no_argument, NULL, 'k'}, {"output", required_argument, NULL, 'o'}, {"hex-dump", required_argument, NULL, 'x'}, {"idle-timeout", required_argument, NULL, 'i'}, @@ -191,7 +192,7 @@ while (1) { /* handle command line arguments */ int option_index; - int c = getopt_long(argc, argv, "46Cc:e:g:G:i:m:hp:d:lo:x:ts:uvw:n", + int c = getopt_long(argc, argv, "46Cc:e:g:G:i:m:hp:d:klo:x:ts:uvw:n", long_options, &option_index); /* That's the end of the options. */ @@ -263,6 +264,9 @@ case 's': source = optarg; break; + case 'k': + o.keepopen = 1; + break; case 'l': o.listen = 1; break; @@ -371,6 +375,7 @@ printf(" -p, --source-port port Specify source port to use (doesn't affect -l)\n"); printf(" -s, --source addr Specify source address to use (doesn't affect -l)\n"); printf(" -l, --listen Bind and listen for incoming connections\n"); + printf(" -k, --keep-open Keep listening after first connection is closed\n"); printf(" -n, --nodns Do not resolve hostnames via DNS\n"); printf(" -t, --telnet Answer Telnet negotiations\n"); printf(" -u, --udp Use UDP instead of default TCP\n"); @@ -553,6 +558,10 @@ if (o.cmdexec && o.hexlogfd != -1) bye("Invalid option combination: `-e' and `-x'."); + /* keep-open requires listen mode. */ + if (o.keepopen && !o.listen) + bye("Invalid option combination: `-k' without `-l'."); + if (o.listen) return ncat_listen_mode(); else Index: ncat/ncat_core.c =================================================================== --- ncat/ncat_core.c (revision 12996) +++ ncat/ncat_core.c (working copy) @@ -38,6 +38,7 @@ o.af = AF_INET; o.broker = 0; o.listen = 0; + o.keepopen = 0; o.sendonly = 0; o.recvonly = 0; o.telnet = 0;
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Attachment:
_bin
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [PATCH] [Ncat] Fix EOF handling Daniel Roethlisberger (Apr 18)
- Re: [PATCH] [Ncat] Fix EOF handling bensonk (Apr 18)
- Re: [PATCH] [Ncat] Fix EOF handling Daniel Roethlisberger (Apr 19)
- Re: [PATCH] [Ncat] Fix EOF handling David Fifield (Apr 19)
- Re: [PATCH] [Ncat] Fix EOF handling Daniel Roethlisberger (Apr 19)
- Re: [PATCH] [Ncat] Fix EOF handling David Fifield (Apr 19)
- Re: [PATCH] [Ncat] Fix EOF handling (client-side) Daniel Roethlisberger (May 02)
- Re: [PATCH] [Ncat] Fix EOF handling (client-side) David Fifield (May 03)
- Re: [PATCH] [Ncat] Fix EOF handling (server side) Daniel Roethlisberger (May 02)
- Re: [PATCH] [Ncat] Fix EOF handling (server side) David Fifield (May 03)
- Re: [PATCH] [Ncat] Fix EOF handling Daniel Roethlisberger (Apr 19)
- Re: [PATCH] [Ncat] Fix EOF handling bensonk (Apr 18)
- Re: [PATCH] [Ncat] Fix EOF handling David Fifield (Jun 01)
- Re: [PATCH] [Ncat] Fix EOF handling Daniel Roethlisberger (Jun 02)