static void connect_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); assert(type == NSE_TYPE_CONNECT || type == NSE_TYPE_CONNECT_SSL); if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else { assert(status == NSE_STATUS_SUCCESS); } #ifdef HAVE_OPENSSL if (nsi_checkssl(cs.sock_nsi)) { /* Check the domain name. ssl_post_connect_check prints an error message if appropriate. */ if (!ssl_post_connect_check((SSL *) nsi_getssl(cs.sock_nsi), o.target)) bye("Certificate verification error."); } #endif connect_report(cs.sock_nsi); /* Create IOD for nsp->stdin */ if ((cs.stdin_nsi = nsi_new2(nsp, 0, NULL)) == NULL) bye("Failed to create stdin nsiod."); post_connect(nsp, nse_iod(evt)); }
static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); char *buf, *tmp = NULL; int nbytes; assert(type == NSE_TYPE_READ); if (status == NSE_STATUS_EOF) { if (o.sendonly) { /* In --send-only mode, exit after EOF on stdin. */ nsock_loop_quit(nsp); } else { shutdown(nsi_getsd(cs.sock_nsi), SHUT_WR); } return; } else if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) { return; } else { assert(status == NSE_STATUS_SUCCESS); } buf = nse_readbuf(evt, &nbytes); /* read from stdin */ if (o.linedelay) ncat_delay_timer(o.linedelay); if (o.crlf) { if (fix_line_endings(buf, &nbytes, &tmp, &cs.crlf_state)) buf = tmp; } nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, buf, nbytes); ncat_log_send(buf, nbytes); if (tmp) free(tmp); refresh_idle_timer(nsp); }
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); char *buf; int nbytes; ncat_assert(type == NSE_TYPE_READ); if (status == NSE_STATUS_EOF) { Close(STDOUT_FILENO); /* In --recv-only mode or non-TCP mode, exit after EOF on the socket. */ if (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.recvonly)) nsock_loop_quit(nsp); return; } else if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) { return; } else { ncat_assert(status == NSE_STATUS_SUCCESS); } buf = nse_readbuf(evt, &nbytes); if (o.linedelay) ncat_delay_timer(o.linedelay); if (o.telnet) dotelnet(nsi_getsd(nse_iod(evt)), (unsigned char *) buf, nbytes); /* Write socket data to stdout */ Write(STDOUT_FILENO, buf, nbytes); ncat_log_recv(buf, nbytes); nsock_readbytes(nsp, cs.sock_nsi, read_socket_handler, -1, NULL, 0); refresh_idle_timer(nsp); }
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); assert(type == NSE_TYPE_WRITE); if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) { return; } else { assert(status == NSE_STATUS_SUCCESS); } /* The write to the socket was successful. Allow reading more from stdin now. */ nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0); }
static void connect_handler(nsock_pool nsp, nsock_event nse, void *udata) { struct connect_test_data *ctd; ctd = (struct connect_test_data *)nsp_getud(nsp); switch(nse_status(nse)) { case NSE_STATUS_SUCCESS: ctd->connect_result = 0; break; case NSE_STATUS_ERROR: ctd->connect_result = -(nse_errorcode(nse)); break; case NSE_STATUS_TIMEOUT: ctd->connect_result = -ETIMEDOUT; break; default: ctd->connect_result = -EINVAL; break; } }
void telnet_event_handler(nsock_pool nsp, nsock_event nse, void *mydata) { nsock_iod nsi = nse_iod(nse); enum nse_status status = nse_status(nse); enum nse_type type = nse_type(nse); struct sockaddr_in peer; struct telnet_state *ts; int nbytes; char *str; int read_timeout = -1; int write_timeout = 2000; ts = (struct telnet_state *)mydata; printf("telnet_event_handler: Received callback of type %s with status %s\n", nse_type2str(type), nse_status2str(status)); if (status == NSE_STATUS_SUCCESS) { switch (type) { case NSE_TYPE_CONNECT: case NSE_TYPE_CONNECT_SSL: nsi_getlastcommunicationinfo(nsi, NULL, NULL, NULL, (struct sockaddr *)&peer, sizeof peer); printf("Successfully connected %sto %s:%hu -- start typing lines\n", (type == NSE_TYPE_CONNECT_SSL) ? "(SSL!) " : "", inet_ntoa(peer.sin_addr), peer.sin_port); /* First of all, lets add STDIN to our list of watched filehandles */ if ((ts->stdin_nsi = nsi_new2(nsp, STDIN_FILENO, NULL)) == NULL) { fprintf(stderr, "Failed to create stdin msi\n"); exit(1); } /* Now lets read from stdin and the network, line buffered (by nsock) */ ts->latest_readtcpev = nsock_readlines(nsp, ts->tcp_nsi, telnet_event_handler, read_timeout, ts, 1); ts->latest_readstdinev = nsock_readlines(nsp, ts->stdin_nsi, telnet_event_handler, read_timeout, ts, 1); break; case NSE_TYPE_READ: str = nse_readbuf(nse, &nbytes); if (nsi == ts->tcp_nsi) { printf("%s", str); /* printf("Read from tcp socket (%d bytes):\n%s", nbytes, str); */ ts->latest_readtcpev = nsock_readlines(nsp, ts->tcp_nsi, telnet_event_handler, read_timeout, ts, 1); } else { /* printf("Read from stdin (%d bytes):\n%s", nbytes, str); */ nsock_write(nsp, ts->tcp_nsi, telnet_event_handler, write_timeout, ts, str, nbytes); ts->latest_readstdinev = nsock_readlines(nsp, ts->stdin_nsi, telnet_event_handler, read_timeout, ts, 1); } break; case NSE_TYPE_WRITE: /* Nothing to do, really */ break; case NSE_TYPE_TIMER: break; default: fprintf(stderr, "telnet_event_handler: Got bogus type -- quitting\n"); exit(1); break; } } else if (status == NSE_STATUS_EOF) { printf("Got EOF from %s\nCancelling outstanding readevents.\n", (nsi == ts->tcp_nsi) ? "tcp socket" : "stdin"); /* One of these is the event I am currently handling! But I wanted to be evil when testing this out... */ if (nsock_event_cancel(nsp, ts->latest_readtcpev, 1) != 0) { printf("Cancelled tcp event: %li\n", ts->latest_readtcpev); } if (nsock_event_cancel(nsp, ts->latest_readstdinev, 1) != 0) { printf("Cancelled stdin event: %li\n", ts->latest_readstdinev); } } else if (status == NSE_STATUS_ERROR) { if (nsi_checkssl(nsi)) { printf("SSL %s failed: %s\n", nse_type2str(type), ERR_error_string(ERR_get_error(), NULL)); } else { int err; err = nse_errorcode(nse); printf("%s failed: (%d) %s\n", nse_type2str(type), err, strerror(err)); } } return; }