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)
