"Titchener, Tom" <[EMAIL PROTECTED]>:
> Ever try connecting to an SSLeay server that uses
> SSLv23_server_method() via a telnet session and then closing the
> session without sending any data?
>
> When you do that in our server, it crashes trying to use the
> handshake_func function in ssl23_read(), 'cuz handshake_func never got
> initialized.
>
> One fix that works is to change this code in the s23_srvr.c
> ssl23_get_client_hello() routine from this:
>
> n=ssl23_read_bytes(s,7);
> if (n != 7) return(n);
>
> to this:
>
> n=ssl23_read_bytes(s,7);
> if (n != 7) return -1;
>
> In SSLeay-0.9.0b, that's lines 210 and 211.
>
> From a quick look at the current sources in OpenSSL, I'd say this
> is still a problem.
I looked into the source and think that it is not a problem (any
more?), and I also couldn't make out any relevant modifications in the
diff between 0.9.0b and 0.9.2b. openssl s_client does not seem to
have problems with incoming connections that are closed without having
sent any data. Is the server that you were testing really running
0.9.0b, or is it an older version?
Definitely the code above is not particularly clear, though.
In a more verbose programming style, it would be
n=ssl23_read_bytes(s,7);
if (n != 7) {
assert(n == 0 || n == -1);
return(n);
}
because ssl23_read_bytes is constructed to be called as often as
necessary to collect the requested number of bytes and won't return
something less than the requested number of bytes if only partial
reads succed, with the exception of 0 if EOF occured in which case the
protocol cannot procees any more. The call to ssl23_get_client_hello
in ssl23_accept is:
case SSL23_ST_SR_CLNT_HELLO_A:
case SSL23_ST_SR_CLNT_HELLO_B:
s->shutdown=0;
ret=ssl23_get_client_hello(s);
if (ret >= 0) cb=NULL;
goto end;
[...]
end:
if (cb != NULL)
cb(s,SSL_CB_ACCEPT_EXIT,ret);
s->in_handshake--;
return(ret);
}
These return values (-1 = error or retry, 0 = EOF, 1 = success) are
used consistently in the varios handshake functions, I think. But I
haven't yet read all of them.
If handshake_func is not initialised (i.e. is 0 because that's what
SSL_new sets it to), then I guess your application failed to call
SSL_set_accept_state before any of SSL_do_handshake, SSL_read or
SSL_write are used, which it really has to. SSL_set_accept_state is
defined as follows:
void SSL_set_accept_state(SSL *s)
{
s->server=1;
s->shutdown=0;
s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;
s->handshake_func=s->method->ssl_accept;
/* clear the current cipher */
ssl_clear_cipher_ctx(s);
}
> Also, I'd say it's probably also lurking in s3_srvr.c, where
> ssl3_get_client_hello return the number of bytes read by
> ssl3_get_message when !ok and the caller is going to think the call to
> ssl3_get_client_hello didn't fail.
Again I think that the premature returns in ssl3_get_client_hello are
to be read as, e.g.,
n=ssl3_get_message(s,
SSL3_ST_SR_CLNT_HELLO_B,
SSL3_ST_SR_CLNT_HELLO_C,
SSL3_MT_CLIENT_HELLO,
SSL3_RT_MAX_PLAIN_LENGTH,
&ok);
if (!ok) {
assert(n == 0 || n == -1);
return((int)n);
}
and don't cause any problems to the program (but, unfortunately, to
humans trying to understand the implementation -- the "if (n != 7)
return(n);" indeed looked suspicious to me when I first encountered
it).
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]