mirror of
https://github.com/processone/ejabberd.git
synced 2024-07-06 23:22:36 +02:00
Don't ignore Length parameter in tls:recv
This commit is contained in:
parent
60d422eb8e
commit
0b423eb287
|
@ -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.
|
||||
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);
|
||||
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>> ->
|
||||
|
|
|
@ -434,13 +434,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;
|
||||
|
|
|
@ -192,16 +192,9 @@ receive_headers(State) ->
|
|||
_ ->
|
||||
case Data of
|
||||
{ok, Binary} ->
|
||||
process_requests(State, binary_to_list(Binary));
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end.
|
||||
|
||||
process_requests(State, Data) ->
|
||||
{Request, Trail} = parse_request(
|
||||
State,
|
||||
State#state.trail ++ Data),
|
||||
State#state.trail ++ binary_to_list(Binary)),
|
||||
State1 = State#state{trail = Trail},
|
||||
NewState = lists:foldl(
|
||||
fun(D, S) ->
|
||||
|
@ -212,8 +205,6 @@ process_requests(State, Data) ->
|
|||
process_header(S, D)
|
||||
end
|
||||
end, State1, Request),
|
||||
case State1#state.trail of
|
||||
[] ->
|
||||
case NewState#state.end_of_request of
|
||||
true ->
|
||||
ok;
|
||||
|
@ -221,7 +212,8 @@ process_requests(State, Data) ->
|
|||
receive_headers(NewState)
|
||||
end;
|
||||
_ ->
|
||||
process_requests(State1, "")
|
||||
ok
|
||||
end
|
||||
end.
|
||||
|
||||
process_header(State, Data) ->
|
||||
|
@ -599,11 +591,7 @@ recv_data(_State, 0, Acc) ->
|
|||
recv_data(State, Len, Acc) ->
|
||||
case State#state.trail of
|
||||
[] ->
|
||||
Len2 = case State#state.sockmod of
|
||||
gen_tcp -> Len;
|
||||
_ -> 0
|
||||
end,
|
||||
case (State#state.sockmod):recv(State#state.socket, Len2, 300000) of
|
||||
case (State#state.sockmod):recv(State#state.socket, Len, 300000) of
|
||||
{ok, Data} ->
|
||||
recv_data(State, Len - size(Data), [Acc | [Data]]);
|
||||
_ ->
|
||||
|
|
Loading…
Reference in New Issue
Block a user