25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

Don't ignore Length parameter in tls:recv

This commit is contained in:
Paweł Chmielowski 2012-04-06 11:53:21 +02:00
parent 4637e2c66b
commit af2e9169e6
2 changed files with 30 additions and 16 deletions

View File

@ -32,7 +32,7 @@
-export([start/0, start_link/0,
tcp_to_tls/2, tls_to_tcp/1,
send/2,
recv/2, recv/3, recv_data/2,
recv/2, recv/3,
setopts/2,
sockname/1, peername/1,
controlling_process/2,
@ -160,29 +160,34 @@ tls_to_tcp(#tlssock{tcpsock = TCPSocket, tlsport = Port}) ->
recv(Socket, Length) ->
recv(Socket, Length, infinity).
recv(#tlssock{tcpsock = TCPSocket} = TLSSock,
_Length, Timeout) ->
%% The Length argument cannot be used for gen_tcp:recv/3, because the
%% compressed size does not equal the desired uncompressed one.
case gen_tcp:recv(TCPSocket, 0, Timeout) of
{ok, Packet} ->
recv_data(TLSSock, Packet);
{error, _Reason} = Error ->
Error
recv(#tlssock{tcpsock = TCPSocket, tlsport = Port} = TLSSock,
Length, Timeout) ->
case port_control(Port, ?GET_DECRYPTED_INPUT, <<Length:32>>) of
<<0>> ->
case gen_tcp:recv(TCPSocket, 0, Timeout) of
{ok, Packet} ->
recv_data(TLSSock, Packet, Length);
{error, _Reason} = Error ->
Error
end;
<<0, In/binary>> ->
{ok, In};
<<1, Error/binary>> ->
{error, binary_to_list(Error)}
end.
recv_data(TLSSock, Packet) ->
case catch recv_data1(TLSSock, Packet) of
recv_data(TLSSock, Packet, Length) ->
case catch recv_data1(TLSSock, Packet, Length) of
{'EXIT', Reason} ->
{error, Reason};
Res ->
Res
end.
recv_data1(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet) ->
recv_data1(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet, Length) ->
case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of
<<0>> ->
case port_control(Port, ?GET_DECRYPTED_INPUT, []) of
case port_control(Port, ?GET_DECRYPTED_INPUT, <<Length:32>>) of
<<0, In/binary>> ->
case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
<<0, Out/binary>> ->

View File

@ -432,13 +432,22 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle,
"SSL_do_handshake failed");
}
if (SSL_is_init_finished(d->ssl)) {
size_t req_size = 0;
if (len == 4)
{
req_size =
(buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
size = BUF_SIZE + 1;
rlen = 1;
b = driver_alloc_binary(size);
b->orig_bytes[0] = 0;
while ((res = SSL_read(d->ssl,
b->orig_bytes + rlen, BUF_SIZE)) > 0)
while ((req_size == 0 || rlen < req_size + 1) &&
(res = SSL_read(d->ssl,
b->orig_bytes + rlen,
(req_size == 0 || req_size + 1 >= size) ?
size - rlen : req_size + 1 - rlen)) > 0)
{
//printf("%d bytes of decrypted data read from state machine\r\n",res);
rlen += res;