


CLOSE_WAIT check
------------------

Ncrack will now check if the connection has been closed by the peer before
trying out a new authentication attempt within that connection. It does that
by issuing a read call (through nsock) with a tiny timeout. If nsock returns
NSE_STATUS_TIMEOUT instead of an NSE_STATUS_EOF, then our connection hasn't been
closed yet by the peer. Of course we check that by using an additional boolean
variable so as to differentiate between normal timeouts and this particular
one. There is not really any other *portable* way to check if our connection
is in CLOSE_WAIT state (e.g Linux netstat just parses /proc and *BSD use
fcntl et al)



NextPair Problem
------------------

Problem: each service that needs to be cracked holds a pointer to the loaded
username list and password list (they are vector objects). Each time a new
connection is made or a new authentication attempt is going to be tried in the
current connection then we need to call NextPair() which gives us the next login
username and password pair. The normal way to do that would be to just move the
password list iterator each time, and the username list iterator once the
password list iterator has finished one full iteration. However, by using this
crude approach arises the following problem: 

-- What happens when a connection is prematurely closed by the peer for one
reason or another (before the current login pair is actually tested)? --

It is obvious that the iterator approach would never really try out that pair,
because it would just forget about the unfinished authentication attempt and
move on giving the next (always unique) pair.

Solution: (still needs to be more tested for some end-cases)

Each time a connection is prematurely closed by the peer, which essentially
means that our current authentication attempt was not completed, then we throw
the current pair inside the service's login-pair pool (which is a stl list). The
next time we are going to ask for a pair from NextPair(), if the pair_pool
is not empty, then it will return us one element from that, giving us the
opportunity to retry that pair once again. The element is removed from the pool
when we extract it from NextPair() and if the authentication doesn't finish this
time either, then we move it back to the list so it can be reused later once
again (and this will go on happening until the authentication finishes all steps
for that pair or any other pair in that situation).

The problem, however, is a little more complex than it first seems:

-- What happens if                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             