Nmap Development mailing list archives
Re: Ncat and windows line endings
From: jah <jah () zadkiel plus com>
Date: Thu, 04 Jun 2009 16:25:11 +0100
On 04/06/2009 02:30, David Fifield wrote:
Here is the patch. It sets _O_TEXT mode on stdin when the input is from the console (checked using the _isatty function), and _O_BINARY otherwise. It sets _O_BINARY on stdout. So the terminal sends \n for line endings, and no newline translation is done anywhere else, just like on Unix. The only problem I can envision is if it's somehow possible to fool _isatty. I can confirm that it returns true for ncat target and false for ncat target < infile cat infile | ncat target but there might be other cases. Documentation is here: http://msdn.microsoft.com/en-us/library/f4s0ddew(VS.80).aspx Setting _O_BINARY on stdout fixes another bug that was not discovered until now. Ncat on Windows was doing newline translation on output as well, breaking binary transfers. unix$ md5sum /etc/services aca587f0966a6f14536dae8fa15f095a /etc/services C:\> ncat.exe -l > services unix$ ncat win --send-only < /etc/services C:\> C:\cygwin\bin\md5sum.exe services 4458bb84b47c93cfa7f5e2432f21ca68 *services What do you think?
This sounds like a good idea and it certainly would dispense with the need for an -L option which should be a good thing. I've attached the half of the patch I previously [1] posted that converts LF to CRLF throughout the buffer. Thanks a bug report from Venkat Sanaka I've fixed an error I made in the original patch too. jah [1] http://seclists.org/nmap-dev/2009/q2/0370.html
diff -urNb r13551/ncat/ncat_broker.c r13551_crlf/ncat/ncat_broker.c --- r13551/ncat/ncat_broker.c 2009-06-04 13:54:58.640625000 +0100 +++ r13551_crlf/ncat/ncat_broker.c 2009-06-04 03:43:25.031250000 +0100 @@ -195,6 +195,7 @@ { char buf[DEFAULT_TCP_BUF_LEN]; char *chatbuf, *outbuf; + char *tempbuf = NULL; struct fdinfo *fdn = get_fdinfo(&fdlist, recv_fd); ssize_t nbytes; fd_set fds; @@ -209,7 +210,7 @@ #endif if (recv_fd == STDIN_FILENO) { /* Behavior differs depending on whether this is stdin or a socket. */ - nbytes = read(recv_fd, buf, sizeof(buf) - o.crlf); + nbytes = read(recv_fd, buf, sizeof(buf)); if (nbytes <= 0) { if (nbytes < 0 && o.verbose) logdebug("Error reading from stdin: %s\n", strerror(errno)); @@ -225,11 +226,8 @@ return; } - /* We gave ourselves extra room in our special-case stdin read above */ - if (o.crlf && buf[nbytes - 1] == '\n' && buf[nbytes - 2] != '\r') { - memcpy(&buf[nbytes - 1], "\r\n", 2); - nbytes++; - } + if (o.crlf) + fix_line_endings((char *) buf, &nbytes, &tempbuf); } else { /* From a connected socket, not stdin. */ nbytes = recv(recv_fd, buf, sizeof(buf), 0); @@ -270,10 +268,14 @@ logdebug("Handling data from client %d.\n", recv_fd); chatbuf = NULL; + /* tempbuf is in use if we read from STDIN and fixed CRLF */ + if (tempbuf == NULL) outbuf = buf; + else + outbuf = tempbuf; if (o.chat) { - chatbuf = chat_filter(buf, nbytes, recv_fd, &nbytes); + chatbuf = chat_filter(outbuf, nbytes, recv_fd, &nbytes); if (chatbuf == NULL) { if (o.verbose) logdebug("Error formatting chat message from fd %d\n", recv_fd); @@ -291,6 +293,8 @@ broadcast(&fds, &fdlist, outbuf, nbytes); free(chatbuf); + free(tempbuf); + tempbuf = NULL; #ifdef HAVE_OPENSSL /* SSL can buffer our input, so doing another select() diff -urNb r13551/ncat/ncat_connect.c r13551_crlf/ncat/ncat_connect.c --- r13551/ncat/ncat_connect.c 2009-06-04 13:54:58.312500000 +0100 +++ r13551_crlf/ncat/ncat_connect.c 2009-06-04 03:56:31.875000000 +0100 @@ -386,12 +386,9 @@ if (o.recvonly == 0) { char *tmp = NULL; - if (o.crlf && buf[nbytes - 1] == '\n' && buf[nbytes - 2] != '\r') { - tmp = (char *) safe_malloc(nbytes + 1); - memcpy(tmp, buf, nbytes - 1); - memcpy(tmp + nbytes - 1, "\r\n", 2); + if (o.crlf) { + if (fix_line_endings(buf, &nbytes, &tmp)) buf = tmp; - nbytes++; } nsock_write(nsp, cs->sock_nsi, connect_evt_handler, diff -urNb r13551/ncat/ncat_listen.c r13551_crlf/ncat/ncat_listen.c --- r13551/ncat/ncat_listen.c 2009-06-04 13:54:58.421875000 +0100 +++ r13551_crlf/ncat/ncat_listen.c 2009-06-04 14:30:39.718750000 +0100 @@ -207,9 +207,10 @@ { int nbytes; char buf[DEFAULT_TCP_BUF_LEN]; + char* write_buf; fd_set fds; - nbytes = read(STDIN_FILENO, buf, sizeof(buf) - o.crlf); + nbytes = read(STDIN_FILENO, buf, sizeof(buf)); if (nbytes <= 0) { if (nbytes < 0 && o.verbose) logdebug("Error reading from stdin: %s\n", strerror(errno)); @@ -225,10 +226,9 @@ return; } - /* We gave ourselves extra room in our special-case stdin read above */ - if (o.crlf && buf[nbytes - 1] == '\n' && buf[nbytes - 2] != '\r') { - memcpy(&buf[nbytes - 1], "\r\n", 2); - nbytes++; + if (!o.crlf || !fix_line_endings((char *) buf, &nbytes, &write_buf)) { + write_buf = (char *) safe_malloc(sizeof(buf)); + memcpy(write_buf, &buf, sizeof(buf)); } if(o.linedelay) @@ -239,7 +239,9 @@ fds = master; FD_CLR(STDIN_FILENO, &fds); FD_CLR(listen_socket, &fds); - broadcast(&fds, &fdlist, buf, nbytes); + broadcast(&fds, &fdlist, write_buf, nbytes); + if (write_buf) + free(write_buf); } /* Read from a client socket and write to stdout. */ diff -urNb r13551/ncat/util.c r13551_crlf/ncat/util.c --- r13551/ncat/util.c 2009-06-04 13:54:58.546875000 +0100 +++ r13551_crlf/ncat/util.c 2009-06-04 15:13:47.890625000 +0100 @@ -442,3 +442,42 @@ fdl->nfds = 0; fdl->fdmax = -1; } + + +/* If any changes need to be made to EOL sequences to comply with --crlf + * then dst will be populated with the modified src, len will be adjusted + * accordingly and the return will be non-zero. + * Returns 0 if changes were not made and len and dst will remain untouched. + */ +int fix_line_endings(char *src, int *len, char **dst) +{ + char *tmp = NULL; + int fix_count; + int i,j; + int num_bytes = *len; + + /* get count of \n without matching \r */ + fix_count = 0; + for (i = 0; i < num_bytes; i++) { + if (src[i] == '\n' && (i == 0 || src[i-1] != '\r')) + fix_count++; + } + if (fix_count <= 0 ) return 0; + + /* now insert matching \r */ + *dst = (char *) safe_malloc(num_bytes + fix_count); + j=0; + + for (i = 0; i < num_bytes; i++) { + if (src[i] == '\n' && (i == 0 || src[i-1] != '\r')) { + memcpy(*dst+j, "\r\n", 2); + j += 2; + } else { + memcpy(*dst+j, src+i, 1); + j++; + } + } + *len += fix_count; + + return 1; +} diff -urNb r13551/ncat/util.h r13551_crlf/ncat/util.h --- r13551/ncat/util.h 2009-06-04 13:54:58.562500000 +0100 +++ r13551_crlf/ncat/util.h 2009-05-15 01:37:32.171875000 +0100 @@ -85,3 +85,5 @@ struct fdinfo *get_fdinfo(const fd_list_t *, int); #endif + +int fix_line_endings(char *src, int *len, char **dst);
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- Ncat and windows line endings jah (May 07)
- Re: Ncat and windows line endings Fyodor (May 08)
- [PATCH] Ncat and windows line endings jah (May 14)
- Re: Ncat and windows line endings David Fifield (Jun 03)
- Re: Ncat and windows line endings David Fifield (Jun 03)
- Re: Ncat and windows line endings jah (Jun 04)
- Re: Ncat and windows line endings David Fifield (Jun 04)
- Re: Ncat and windows line endings David Fifield (Jun 04)
- Re: Ncat and windows line endings Fyodor (May 08)