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)); }
/* Handle --exec if appropriate, otherwise start the initial read events and set the idle timeout. */ static void post_connect(nsock_pool nsp, nsock_iod iod) { /* Command to execute. */ if (o.cmdexec) { struct fdinfo info; info.fd = nsi_getsd(iod); #ifdef HAVE_OPENSSL info.ssl = (SSL *) nsi_getssl(iod); #endif /* Convert Nsock's non-blocking socket to an ordinary blocking one. It's possible for a program to write fast enough that it will get an EAGAIN on write on a non-blocking socket. */ block_socket(info.fd); netexec(&info, o.cmdexec); } /* Start the initial reads. */ if (!o.sendonly) nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL); if (!o.recvonly) nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0); /* The --idle-timeout option says to exit after a certain period of inactivity. We start a timer here and reset it on every read event; see refresh_idle_timer. */ if (o.idletimeout > 0) { cs.idle_timer_event_id = nsock_timer_create(nsp, idle_timer_handler, o.idletimeout, NULL); } }
/* Depending on verbosity, print a message that a connection was established. */ static void connect_report(nsock_iod nsi) { union sockaddr_u peer; zmem(&peer, sizeof(peer.storage)); nsi_getlastcommunicationinfo(nsi, NULL, NULL, NULL, &peer.sockaddr, sizeof(peer.storage)); if (o.verbose) { #ifdef HAVE_OPENSSL if (nsi_checkssl(nsi)) { X509 *cert; X509_NAME *subject; char digest_buf[SHA1_STRING_LENGTH + 1]; char *fp; loguser("SSL connection to %s:%hu.", inet_socktop(&peer), nsi_peerport(nsi)); cert = SSL_get_peer_certificate((SSL *) nsi_getssl(nsi)); ncat_assert(cert != NULL); subject = X509_get_subject_name(cert); if (subject != NULL) { char buf[256]; int n; n = X509_NAME_get_text_by_NID(subject, NID_organizationName, buf, sizeof(buf)); if (n >= 0 && n <= sizeof(buf) - 1) loguser_noprefix(" %s", buf); } loguser_noprefix("\n"); fp = ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)); ncat_assert(fp == digest_buf); loguser("SHA-1 fingerprint: %s\n", digest_buf); } else { #if HAVE_SYS_UN_H if (peer.sockaddr.sa_family == AF_UNIX) loguser("Connected to %s.\n", peer.un.sun_path); else #endif loguser("Connected to %s:%hu.\n", inet_socktop(&peer), nsi_peerport(nsi)); } #else #if HAVE_SYS_UN_H if (peer.sockaddr.sa_family == AF_UNIX) loguser("Connected to %s.\n", peer.un.sun_path); else #endif loguser("Connected to %s:%hu.\n", inet_socktop(&peer), nsi_peerport(nsi)); #endif } }