Fixed a couple nsock problems described in

http://seclists.org/nmap-dev/2012/q3/56.  r29134 already addressed the issue but
was incomplete.

This replaces r29134 with an engine-agnostic approach, and additionally enforces
the reset of IOD flags before use or re-use.
This commit is contained in:
henri 2012-07-09 16:45:49 +00:00
parent 47d8b75fcf
commit 87fcddad2b
5 changed files with 18 additions and 11 deletions

View file

@ -22,7 +22,8 @@ o [NSE] Added tls-nextprotoneg script which enumerates a TLS server's supported
o [NSOCK] Fixed an epoll-engine-specific bug. The engine didn't recognized FDs
that were internally closed and replaced by other ones. This happened during
reconnect attempts. [Henri Doreau]
reconnect attempts. Also, the IOD flags were not properly cleared.
[Henri Doreau, Daniel Miller]
o Added support for log type bitmasks in log_vwrite(). Also replaced a fatal()
statement by an assert(0) to get rid of a possible infinite call loop when

View file

@ -207,6 +207,7 @@ int epoll_iod_modify(mspool *nsp, msiod *iod, int ev_set, int ev_clr) {
struct epoll_engine_info *einfo = (struct epoll_engine_info *)nsp->engine_data;
assert((ev_set & ev_clr) == 0);
assert(IOD_PROPGET(iod, IOD_REGISTERED));
memset(&epev, 0x00, sizeof(struct epoll_event));
epev.events = EPOLLET;
@ -230,16 +231,10 @@ int epoll_iod_modify(mspool *nsp, msiod *iod, int ev_set, int ev_clr) {
epev.events |= EPOLL_X_FLAGS;
sd = nsi_getsd(iod);
if (epoll_ctl(einfo->epfd, EPOLL_CTL_MOD, sd, &epev) < 0) {
if (errno == ENOENT) {
/* This IOD is registered but its associated fd is not in the epoll set.
* It was probably closed and another one was open (e.g.: reconnect operation).
* We therefore want to add the new one. */
epoll_ctl(einfo->epfd, EPOLL_CTL_ADD, sd, &epev);
} else {
fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno));
}
}
if (epoll_ctl(einfo->epfd, EPOLL_CTL_MOD, sd, &epev) < 0)
fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno));
return 1;
}

View file

@ -208,8 +208,10 @@ int select_iod_unregister(mspool *nsp, msiod *iod) {
{
CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_r);
CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_w);
CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_x);
CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_r);
CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_w);
CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_x);
}
if (sinfo->max_sd == iod->sd)

View file

@ -462,6 +462,8 @@ void handle_connect_result(mspool *ms, msevent *nse, enum nse_status status) {
socket_count_write_inc(iod);
update_events(iod, ms, EV_WRITE, EV_NONE);
} else if (!(options & SSL_OP_NO_SSLv2)) {
int saved_ev;
/* SSLv3-only and TLSv1-only servers can't be connected to when the
* SSL_OP_NO_SSLv2 option is not set, which is the case when the pool
* was initialized with nsp_ssl_init_max_speed. Try reconnecting with
@ -469,8 +471,13 @@ void handle_connect_result(mspool *ms, msevent *nse, enum nse_status status) {
* might use SSLv2. */
if (ms->tracelevel > 0)
nsock_trace(ms, "EID %li reconnecting with SSL_OP_NO_SSLv2", nse->id);
saved_ev = iod->watched_events;
ms->engine->iod_unregister(ms, iod);
close(iod->sd);
nsock_connect_internal(ms, nse, iod->lastproto, &iod->peer, iod->peerlen, nsi_peerport(iod));
ms->engine->iod_register(ms, iod, saved_ev);
SSL_clear(iod->ssl);
if(!SSL_clear(iod->ssl))
fatal("SSL_clear failed: %s", ERR_error_string(ERR_get_error(), NULL));

View file

@ -121,6 +121,8 @@ nsock_iod nsi_new2(nsock_pool nsockp, int sd, void *userdata) {
nsi->userdata = userdata;
nsi->nsp = (mspool *)nsockp;
nsi->_flags = 0;
nsi->read_count = 0;
nsi->write_count = 0;