Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mtproto_proxy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
mtproto_proxy
Commits
30f7e6b9
Unverified
Commit
30f7e6b9
authored
Aug 15, 2019
by
Sergey Prokhorov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add fake-tls support to mtp_test_client; added TLS networking tests
parent
5fd6971f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
161 additions
and
41 deletions
+161
-41
mtp_fake_tls.erl
src/mtp_fake_tls.erl
+101
-30
mtp_obfuscated.erl
src/mtp_obfuscated.erl
+7
-4
mtp_test_client.erl
test/mtp_test_client.erl
+28
-5
prop_mtp_statefull.erl
test/prop_mtp_statefull.erl
+5
-2
single_dc_SUITE.erl
test/single_dc_SUITE.erl
+19
-0
test-sys.config
test/test-sys.config
+1
-0
No files found.
src/mtp_fake_tls.erl
View file @
30f7e6b9
...
@@ -17,6 +17,12 @@
...
@@ -17,6 +17,12 @@
try_decode_packet
/
2
,
try_decode_packet
/
2
,
decode_all
/
2
,
decode_all
/
2
,
encode_packet
/
2
]).
encode_packet
/
2
]).
-
ifdef
(
TEST
).
-
export
([
make_client_hello
/
2
,
make_client_hello
/
4
,
parse_server_hello
/
1
]).
-
endif
.
-
export_type
([
codec
/
0
,
meta
/
0
]).
-
export_type
([
codec
/
0
,
meta
/
0
]).
-
include_lib
(
"hut/include/hut.hrl"
).
-
include_lib
(
"hut/include/hut.hrl"
).
...
@@ -33,6 +39,9 @@
...
@@ -33,6 +39,9 @@
extensions
::
[{
non_neg_integer
(),
any
()}]
extensions
::
[{
non_neg_integer
(),
any
()}]
}).
}).
-
define
(
u16
,
16
/
unsigned
-
big
).
-
define
(
u24
,
24
/
unsigned
-
big
).
-
define
(
MAX_IN_PACKET_SIZE
,
65535
).
% sizeof(uint16) - 1
-
define
(
MAX_IN_PACKET_SIZE
,
65535
).
% sizeof(uint16) - 1
-
define
(
MAX_OUT_PACKET_SIZE
,
16384
).
% 2^14 https://tools.ietf.org/html/rfc8446#section-5.1
-
define
(
MAX_OUT_PACKET_SIZE
,
16384
).
% 2^14 https://tools.ietf.org/html/rfc8446#section-5.1
...
@@ -51,12 +60,6 @@
...
@@ -51,12 +60,6 @@
-
define
(
TLS_TAG_CLI_HELLO
,
1
).
-
define
(
TLS_TAG_CLI_HELLO
,
1
).
-
define
(
TLS_TAG_SRV_HELLO
,
2
).
-
define
(
TLS_TAG_SRV_HELLO
,
2
).
-
define
(
TLS_CIPHERSUITE
,
192
,
47
).
-
define
(
TLS_CIPHERSUITE
,
192
,
47
).
-
define
(
TLS_EXTENSIONS
,
0
,
18
,
% Extensions length
255
,
1
,
0
,
1
,
0
,
% renegotiation_info
0
,
5
,
0
,
0
,
% status_request
0
,
16
,
0
,
5
,
0
,
3
,
2
,
104
,
50
% ALPN
).
-
define
(
TLS_CHANGE_CIPHER
,
?
TLS_REC_CHANGE_CIPHER
,
?
TLS_12_VERSION
,
0
,
1
,
1
).
-
define
(
TLS_CHANGE_CIPHER
,
?
TLS_REC_CHANGE_CIPHER
,
?
TLS_12_VERSION
,
0
,
1
,
1
).
-
define
(
EXT_SNI
,
0
).
-
define
(
EXT_SNI
,
0
).
...
@@ -90,7 +93,7 @@ urlencode_digit($/) -> $_;
...
@@ -90,7 +93,7 @@ urlencode_digit($/) -> $_;
urlencode_digit
(
$+
)
->
$-
;
urlencode_digit
(
$+
)
->
$-
;
urlencode_digit
(
D
)
->
D
.
urlencode_digit
(
D
)
->
D
.
%% Parse fake-TLS "ClientHello" packet and generate "ServerHello + ChangeCipher + ApplicationData"
-
spec
from_client_hello
(
binary
(),
binary
())
->
-
spec
from_client_hello
(
binary
(),
binary
())
->
{
ok
,
iodata
(),
meta
(),
codec
()}.
{
ok
,
iodata
(),
meta
(),
codec
()}.
from_client_hello
(
Data
,
Secret
)
->
from_client_hello
(
Data
,
Secret
)
->
...
@@ -99,11 +102,10 @@ from_client_hello(Data, Secret) ->
...
@@ -99,11 +102,10 @@ from_client_hello(Data, Secret) ->
extensions
=
Extensions
}
=
CliHlo
=
parse_client_hello
(
Data
),
extensions
=
Extensions
}
=
CliHlo
=
parse_client_hello
(
Data
),
?
log
(
debug
,
"TLS ClientHello=
~p
"
,
[
CliHlo
]),
?
log
(
debug
,
"TLS ClientHello=
~p
"
,
[
CliHlo
]),
ServerDigest
=
make_server_digest
(
Data
,
Secret
),
ServerDigest
=
make_server_digest
(
Data
,
Secret
),
<<
Zeroes
:(
?
DIGEST_LEN
-
4
)
/
binary
,
_
/
binary
>>
=
XoredDigest
=
<<
Zeroes
:(
?
DIGEST_LEN
-
4
)
/
binary
,
Timestamp
:
32
/
unsigned
-
little
>>
=
XoredDigest
=
crypto
:
exor
(
ClientDigest
,
ServerDigest
),
crypto
:
exor
(
ClientDigest
,
ServerDigest
),
lists
:
all
(
fun
(
B
)
->
B
==
0
end
,
binary_to_list
(
Zeroes
))
orelse
lists
:
all
(
fun
(
B
)
->
B
==
0
end
,
binary_to_list
(
Zeroes
))
orelse
error
({
protocol_error
,
tls_invalid_digest
,
XoredDigest
}),
error
({
protocol_error
,
tls_invalid_digest
,
XoredDigest
}),
<<
_:(
?
DIGEST_LEN
-
4
)
/
binary
,
Timestamp
:
32
/
unsigned
-
little
>>
=
XoredDigest
,
KeyShare
=
make_key_share
(
Extensions
),
KeyShare
=
make_key_share
(
Extensions
),
SrvHello0
=
make_srv_hello
(
binary
:
copy
(
<<
0
>>
,
?
DIGEST_LEN
),
SessionId
,
KeyShare
),
SrvHello0
=
make_srv_hello
(
binary
:
copy
(
<<
0
>>
,
?
DIGEST_LEN
),
SessionId
,
KeyShare
),
FakeHttpData
=
crypto
:
strong_rand_bytes
(
rand
:
uniform
(
256
)),
FakeHttpData
=
crypto
:
strong_rand_bytes
(
rand
:
uniform
(
256
)),
...
@@ -127,13 +129,13 @@ from_client_hello(Data, Secret) ->
...
@@ -127,13 +129,13 @@ from_client_hello(Data, Secret) ->
{
ok
,
Response
,
Meta
,
new
()}.
{
ok
,
Response
,
Meta
,
new
()}.
parse_client_hello
(
<<?
TLS_REC_HANDSHAKE
,
?
TLS_10_VERSION
,
512
:
16
/
unsigned
-
big
,
%Frame
parse_client_hello
(
<<?
TLS_REC_HANDSHAKE
,
?
TLS_10_VERSION
,
512
:
?
u16
,
%Frame
?
TLS_TAG_CLI_HELLO
,
508
:
24
/
unsigned
-
big
,
?
TLS_12_VERSION
,
?
TLS_TAG_CLI_HELLO
,
508
:
?
u24
,
?
TLS_12_VERSION
,
Random
:
?
DIGEST_LEN
/
binary
,
Random
:
?
DIGEST_LEN
/
binary
,
SessIdLen
,
SessId
:
SessIdLen
/
binary
,
SessIdLen
,
SessId
:
SessIdLen
/
binary
,
CipherSuitesLen
:
16
/
unsigned
-
big
,
CipherSuites
:
CipherSuitesLen
/
binary
,
CipherSuitesLen
:
?
u16
,
CipherSuites
:
CipherSuitesLen
/
binary
,
CompMethodsLen
,
CompMethods
:
CompMethodsLen
/
binary
,
CompMethodsLen
,
CompMethods
:
CompMethodsLen
/
binary
,
ExtensionsLen
:
16
/
unsigned
-
big
,
Extensions
:
ExtensionsLen
/
binary
>>
ExtensionsLen
:
?
u16
,
Extensions
:
ExtensionsLen
/
binary
>>
%% _/binary>>
%% _/binary>>
)
->
)
->
#client_hello
{
#client_hello
{
...
@@ -145,21 +147,21 @@ parse_client_hello(<<?TLS_REC_HANDSHAKE, ?TLS_10_VERSION, 512:16/unsigned-big, %
...
@@ -145,21 +147,21 @@ parse_client_hello(<<?TLS_REC_HANDSHAKE, ?TLS_10_VERSION, 512:16/unsigned-big, %
}.
}.
parse_suites
(
Bin
)
->
parse_suites
(
Bin
)
->
[
Suite
||
<<
Suite
:
16
/
unsigned
-
big
>>
<=
Bin
].
[
Suite
||
<<
Suite
:
?
u16
>>
<=
Bin
].
parse_compression
(
Bin
)
->
parse_compression
(
Bin
)
->
[
Bin
].
%TODO: just binary_to_list(Bin)
[
Bin
].
%TODO: just binary_to_list(Bin)
parse_extensions
(
Exts
)
->
parse_extensions
(
Exts
)
->
[{
Type
,
parse_extension
(
Type
,
Data
)}
[{
Type
,
parse_extension
(
Type
,
Data
)}
||
<<
Type
:
16
/
unsigned
-
big
,
Length
:
16
/
unsigned
-
big
,
Data
:
Length
/
binary
>>
<=
Exts
].
||
<<
Type
:
?
u16
,
Length
:
?
u16
,
Data
:
Length
/
binary
>>
<=
Exts
].
parse_extension
(
?
EXT_SNI
,
<<
ListLen
:
16
/
unsigned
-
big
,
List
:
ListLen
/
binary
>>
)
->
parse_extension
(
?
EXT_SNI
,
<<
ListLen
:
?
u16
,
List
:
ListLen
/
binary
>>
)
->
[{
Type
,
Value
}
[{
Type
,
Value
}
||
<<
Type
,
Len
:
16
/
unsigned
-
big
,
Value
:
Len
/
binary
>>
<=
List
];
||
<<
Type
,
Len
:
?
u16
,
Value
:
Len
/
binary
>>
<=
List
];
parse_extension
(
?
EXT_KEY_SHARE
,
<<
Len
:
16
/
unsigned
-
big
,
Exts
:
Len
/
binary
>>
)
->
parse_extension
(
?
EXT_KEY_SHARE
,
<<
Len
:
?
u16
,
Exts
:
Len
/
binary
>>
)
->
[{
Group
,
Key
}
[{
Group
,
Key
}
||
<<
Group
:
16
/
unsigned
-
big
,
KeyLen
:
16
/
unsigned
-
big
,
Key
:
KeyLen
/
binary
>>
<=
Exts
];
||
<<
Group
:
?
u16
,
KeyLen
:
?
u16
,
Key
:
KeyLen
/
binary
>>
<=
Exts
];
parse_extension
(_
Type
,
Data
)
->
parse_extension
(_
Type
,
Data
)
->
Data
.
Data
.
...
@@ -212,12 +214,11 @@ make_key_share(Exts) ->
...
@@ -212,12 +214,11 @@ make_key_share(Exts) ->
make_srv_hello
(
Digest
,
SessionId
,
{
KeyShareGroup
,
KeyShareKey
})
->
make_srv_hello
(
Digest
,
SessionId
,
{
KeyShareGroup
,
KeyShareKey
})
->
%% https://tools.ietf.org/html/rfc8446#section-4.1.3
%% https://tools.ietf.org/html/rfc8446#section-4.1.3
KeyShareEntity
=
<<
KeyShareGroup
:
16
/
unsigned
-
big
,
(
byte_size
(
KeyShareKey
)):
16
/
unsigned
-
big
,
KeyShareEntity
=
<<
KeyShareGroup
:
?
u16
,
(
byte_size
(
KeyShareKey
)):
?
u16
,
KeyShareKey
/
binary
>>
,
KeyShareKey
/
binary
>>
,
Extensions
=
Extensions
=
[
<<?
EXT_KEY_SHARE
:
16
/
unsigned
-
big
,
(
byte_size
(
KeyShareEntity
)):
16
/
unsigned
-
big
>>
,
[
<<?
EXT_KEY_SHARE
:
?
u16
,
(
byte_size
(
KeyShareEntity
)):
?
u16
>>
,
KeyShareEntity
,
KeyShareEntity
,
<<?
EXT_SUPPORTED_VERSIONS
:
16
/
unsigned
-
big
,
2
:
16
/
unsigned
-
big
,
?
TLS_13_VERSION
>>
],
<<?
EXT_SUPPORTED_VERSIONS
:
?
u16
,
2
:
?
u16
,
?
TLS_13_VERSION
>>
],
SessionSize
=
byte_size
(
SessionId
),
SessionSize
=
byte_size
(
SessionId
),
Payload
=
[
<<?
TLS_12_VERSION
,
Payload
=
[
<<?
TLS_12_VERSION
,
Digest
:
?
DIGEST_LEN
/
binary
,
Digest
:
?
DIGEST_LEN
/
binary
,
...
@@ -225,10 +226,81 @@ make_srv_hello(Digest, SessionId, {KeyShareGroup, KeyShareKey}) ->
...
@@ -225,10 +226,81 @@ make_srv_hello(Digest, SessionId, {KeyShareGroup, KeyShareKey}) ->
SessionId
:
SessionSize
/
binary
,
SessionId
:
SessionSize
/
binary
,
?
TLS_CIPHERSUITE
,
?
TLS_CIPHERSUITE
,
0
,
% Compression method
0
,
% Compression method
(
iolist_size
(
Extensions
)):
16
/
unsigned
-
big
>>
(
iolist_size
(
Extensions
)):
?
u16
>>
|
Extensions
],
|
Extensions
],
[
<<?
TLS_TAG_SRV_HELLO
,
(
iolist_size
(
Payload
)):
24
/
unsigned
-
big
>>
|
Payload
].
[
<<?
TLS_TAG_SRV_HELLO
,
(
iolist_size
(
Payload
)):
?
u24
>>
|
Payload
].
-
ifdef
(
TEST
).
%% Generate Fake-TLS "ClientHello". Used for tests only.
make_client_hello
(
Secret
,
SniDomain
)
->
make_client_hello
(
erlang
:
system_time
(
second
),
crypto
:
strong_rand_bytes
(
32
),
Secret
,
SniDomain
).
make_client_hello
(
Timestamp
,
SessionId
,
HexSecret
,
SniDomain
)
when
byte_size
(
HexSecret
)
==
32
->
make_client_hello
(
Timestamp
,
SessionId
,
mtp_handler
:
unhex
(
HexSecret
),
SniDomain
);
make_client_hello
(
Timestamp
,
SessionId
,
Secret
,
SniDomain
)
when
byte_size
(
SessionId
)
==
32
,
byte_size
(
Secret
)
==
16
->
%% Wireshark capture from Telegram Desktop
CipherSuites
=
mtp_handler
:
unhex
(
<<
"eaea130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a"
>>
),
CSLen
=
byte_size
(
CipherSuites
),
SNI
=
make_sni
([
SniDomain
]),
%% Wireshark capture from Telegram Desktop
KeyShare
=
mtp_handler
:
unhex
(
<<
"0033002b00295a5a000100001d0020a4146c3e8573565bb5f5c877a88a98dcbbd46a9b3ca1ab3df7217cc33b4b6d2c"
>>
),
SupportedVersions
=
mtp_handler
:
unhex
(
<<
"002b000b0a1a1a0304030303020301"
>>
),
ExtLen
=
401
,
% From wireshark
RealExtensions
=
<<
KeyShare
/
binary
,
SupportedVersions
/
binary
,
SNI
/
binary
>>
,
Extensions
=
add_padding_ext
(
RealExtensions
,
ExtLen
),
(
ExtLen
==
byte_size
(
Extensions
))
orelse
error
({
bad_ext_len
,
byte_size
(
Extensions
)}),
SessIdLen
=
byte_size
(
SessionId
),
Pack
=
fun
(
FakeRandom
)
->
<<?
TLS_REC_HANDSHAKE
,
?
TLS_10_VERSION
,
512
:
?
u16
,
?
TLS_TAG_CLI_HELLO
,
508
:
?
u24
,
?
TLS_12_VERSION
,
FakeRandom
:
?
DIGEST_LEN
/
binary
,
SessIdLen
,
SessionId
:
SessIdLen
/
binary
,
CSLen
:
?
u16
,
CipherSuites
:
CSLen
/
binary
,
1
,
0
,
%Compression methods
ExtLen
:
?
u16
,
Extensions
:
ExtLen
/
binary
>>
end
,
FakeRandom0
=
binary
:
copy
(
<<
0
>>
,
?
DIGEST_LEN
),
Hello0
=
Pack
(
FakeRandom0
),
Digest
=
crypto
:
hmac
(
sha256
,
Secret
,
Hello0
),
EncTimestamp
=
<<
(
binary
:
copy
(
<<
0
>>
,
?
DIGEST_LEN
-
4
))
/
binary
,
Timestamp
:
32
/
unsigned
-
little
>>
,
FakeRandom
=
crypto
:
exor
(
Digest
,
EncTimestamp
),
Pack
(
FakeRandom
).
make_sni
(
Domains
)
->
SniListItems
=
<<
<<?
EXT_SNI_HOST_NAME
,
(
byte_size
(
Domain
)):
?
u16
,
Domain
/
binary
>>
||
Domain
<-
Domains
>>
,
ItemsLen
=
byte_size
(
SniListItems
),
<<?
EXT_SNI
:
?
u16
,
(
ItemsLen
+
2
):
?
u16
,
ItemsLen
:
?
u16
,
SniListItems
/
binary
>>
.
add_padding_ext
(
RealExtensions
,
ExtLen
)
->
RealExtLen
=
byte_size
(
RealExtensions
),
PadSize
=
ExtLen
-
RealExtLen
-
4
,
PaddingExt
=
<<
21
:
?
u16
,
%EXT_PADDING
PadSize
:
?
u16
,
(
binary
:
copy
(
<<
0
>>
,
PadSize
))
/
binary
>>
,
<<
RealExtensions
/
binary
,
PaddingExt
/
binary
>>
.
%% Parses "ServerHello" (the one produced by from_client_hello/2). Used for tests only.
parse_server_hello
(
<<?
TLS_REC_HANDSHAKE
,
?
TLS_12_VERSION
,
HSLen
:
?
u16
,
Handshake
:
HSLen
/
binary
,
?
TLS_REC_CHANGE_CIPHER
,
?
TLS_12_VERSION
,
CCLen
:
?
u16
,
ChangeCipher
:
CCLen
/
binary
,
?
TLS_REC_DATA
,
?
TLS_12_VERSION
,
DLen
:
?
u16
,
Data
:
DLen
/
binary
,
Tail
/
binary
>>
)
->
{
Handshake
,
ChangeCipher
,
Data
,
Tail
};
parse_server_hello
(
B
)
when
byte_size
(
B
)
<
(
512
+
5
)
->
incomplete
.
-
endif
.
%% Data stream codec
-
spec
new
()
->
codec
().
-
spec
new
()
->
codec
().
new
()
->
new
()
->
...
@@ -236,10 +308,9 @@ new() ->
...
@@ -236,10 +308,9 @@ new() ->
-
spec
try_decode_packet
(
binary
(),
codec
())
->
{
ok
,
binary
(),
binary
(),
codec
()}
-
spec
try_decode_packet
(
binary
(),
codec
())
->
{
ok
,
binary
(),
binary
(),
codec
()}
|
{
incomplete
,
codec
()}.
|
{
incomplete
,
codec
()}.
try_decode_packet
(
<<?
TLS_12_DATA
,
Size
:
16
/
unsigned
-
big
,
try_decode_packet
(
<<?
TLS_12_DATA
,
Size
:
?
u16
,
Data
:
Size
/
binary
,
Tail
/
binary
>>
,
St
)
->
Data
:
Size
/
binary
,
Tail
/
binary
>>
,
St
)
->
{
ok
,
Data
,
Tail
,
St
};
{
ok
,
Data
,
Tail
,
St
};
try_decode_packet
(
<<?
TLS_REC_CHANGE_CIPHER
,
?
TLS_12_VERSION
,
Size
:
16
/
unsigned
-
big
,
try_decode_packet
(
<<?
TLS_REC_CHANGE_CIPHER
,
?
TLS_12_VERSION
,
Size
:
?
u16
,
_
Data
:
Size
/
binary
,
Tail
/
binary
>>
,
St
)
->
_
Data
:
Size
/
binary
,
Tail
/
binary
>>
,
St
)
->
%% "Change cipher" are ignored
%% "Change cipher" are ignored
try_decode_packet
(
Tail
,
St
);
try_decode_packet
(
Tail
,
St
);
...
@@ -277,4 +348,4 @@ as_tls_data_frame(Bin) ->
...
@@ -277,4 +348,4 @@ as_tls_data_frame(Bin) ->
-
spec
as_tls_frame
(
byte
(),
iodata
())
->
iodata
().
-
spec
as_tls_frame
(
byte
(),
iodata
())
->
iodata
().
as_tls_frame
(
Type
,
Data
)
->
as_tls_frame
(
Type
,
Data
)
->
Size
=
iolist_size
(
Data
),
Size
=
iolist_size
(
Data
),
[
<<
Type
,
?
TLS_12_VERSION
,
Size
:
16
/
unsigned
-
big
>>
|
Data
].
[
<<
Type
,
?
TLS_12_VERSION
,
Size
:
?
u16
>>
|
Data
].
src/mtp_obfuscated.erl
View file @
30f7e6b9
...
@@ -7,9 +7,7 @@
...
@@ -7,9 +7,7 @@
-
module
(
mtp_obfuscated
).
-
module
(
mtp_obfuscated
).
-
behaviour
(
mtp_codec
).
-
behaviour
(
mtp_codec
).
-
export
([
client_create
/
3
,
-
export
([
from_header
/
2
,
client_create
/
4
,
from_header
/
2
,
new
/
4
,
new
/
4
,
encrypt
/
2
,
encrypt
/
2
,
decrypt
/
2
,
decrypt
/
2
,
...
@@ -17,6 +15,10 @@
...
@@ -17,6 +15,10 @@
encode_packet
/
2
encode_packet
/
2
]).
]).
-
export
([
bin_rev
/
1
]).
-
export
([
bin_rev
/
1
]).
-
ifdef
(
TEST
).
-
export
([
client_create
/
3
,
client_create
/
4
]).
-
endif
.
-
export_type
([
codec
/
0
]).
-
export_type
([
codec
/
0
]).
...
@@ -32,7 +34,7 @@
...
@@ -32,7 +34,7 @@
-
opaque
codec
()
::
#st
{}.
-
opaque
codec
()
::
#st
{}.
-
ifdef
(
TEST
).
client_create
(
Secret
,
Protocol
,
DcId
)
->
client_create
(
Secret
,
Protocol
,
DcId
)
->
client_create
(
crypto
:
strong_rand_bytes
(
58
),
client_create
(
crypto
:
strong_rand_bytes
(
58
),
Secret
,
Protocol
,
DcId
).
Secret
,
Protocol
,
DcId
).
...
@@ -90,6 +92,7 @@ encode_protocol(mtp_secure) ->
...
@@ -90,6 +92,7 @@ encode_protocol(mtp_secure) ->
%% 4byte
%% 4byte
encode_dc_id
(
DcId
)
->
encode_dc_id
(
DcId
)
->
<<
DcId
:
16
/
signed
-
little
-
integer
>>
.
<<
DcId
:
16
/
signed
-
little
-
integer
>>
.
-
endif
.
%% @doc creates new obfuscated stream (MTProto proxy format)
%% @doc creates new obfuscated stream (MTProto proxy format)
-
spec
from_header
(
binary
(),
binary
())
->
{
ok
,
integer
(),
mtp_codec
:
packet_codec
(),
codec
()}
-
spec
from_header
(
binary
(),
binary
())
->
{
ok
,
integer
(),
mtp_codec
:
packet_codec
(),
codec
()}
...
...
test/mtp_test_client.erl
View file @
30f7e6b9
...
@@ -20,20 +20,43 @@ connect(Host, Port, Secret, DcId, Protocol) ->
...
@@ -20,20 +20,43 @@ connect(Host, Port, Secret, DcId, Protocol) ->
Seed
=
crypto
:
strong_rand_bytes
(
58
),
Seed
=
crypto
:
strong_rand_bytes
(
58
),
connect
(
Host
,
Port
,
Seed
,
Secret
,
DcId
,
Protocol
).
connect
(
Host
,
Port
,
Seed
,
Secret
,
DcId
,
Protocol
).
connect
(
Host
,
Port
,
Seed
,
Secret
,
DcId
,
Protocol
)
->
-
spec
connect
(
inet
:
socket_address
()
|
inet
:
hostname
(),
inet
:
port_number
(),
binary
(),
binary
(),
integer
(),
mtp_codec
:
packet_codec
()
|
{
mtp_fake_tls
,
binary
()})
->
client
().
connect
(
Host
,
Port
,
Seed
,
Secret
,
DcId
,
Protocol0
)
->
Opts
=
[{
packet
,
raw
},
Opts
=
[{
packet
,
raw
},
{
mode
,
binary
},
{
mode
,
binary
},
{
active
,
false
},
{
active
,
false
},
{
buffer
,
1024
},
{
buffer
,
1024
},
{
send_timeout
,
5000
}],
{
send_timeout
,
5000
}],
{
ok
,
Sock
}
=
gen_tcp
:
connect
(
Host
,
Port
,
Opts
,
1000
),
{
ok
,
Sock
}
=
gen_tcp
:
connect
(
Host
,
Port
,
Opts
,
1000
),
{
Header
,
_,
_,
CryptoLayer
}
=
mtp_obfuscated
:
client_create
(
Seed
,
Secret
,
Protocol
,
DcId
),
{
Protocol
,
TlsEnabled
,
TlsSt
}
=
case
Protocol0
of
{
mtp_fake_tls
,
Domain
}
->
ClientHello
=
mtp_fake_tls
:
make_client_hello
(
Secret
,
Domain
),
ok
=
gen_tcp
:
send
(
Sock
,
ClientHello
),
%% Let's hope whole server hello will arrive in a single chunk
{
ok
,
ServerHello
}
=
gen_tcp
:
recv
(
Sock
,
0
,
5000
),
%% TODO: if Tail is not empty, use codec:push_back(first, ..)
{_
HS
,
_
CC
,
_
D
,
<<>>
}
=
mtp_fake_tls
:
parse_server_hello
(
ServerHello
),
{
mtp_secure
,
true
,
mtp_fake_tls
:
new
()};
_
->
{
Protocol0
,
false
,
undefined
}
end
,
{
Header0
,
_,
_,
CryptoLayer
}
=
mtp_obfuscated
:
client_create
(
Seed
,
Secret
,
Protocol
,
DcId
),
NoopSt
=
mtp_noop_codec
:
new
(),
%% First, create codec with just TLS (which might be noop as well) to encode "obfuscated" header
Codec0
=
mtp_codec
:
new
(
mtp_noop_codec
,
NoopSt
,
mtp_noop_codec
,
NoopSt
,
TlsEnabled
,
TlsSt
,
25
*
1024
*
1024
),
{
Header
,
Codec1
}
=
mtp_codec
:
encode_packet
(
Header0
,
Codec0
),
ok
=
gen_tcp
:
send
(
Sock
,
Header
),
ok
=
gen_tcp
:
send
(
Sock
,
Header
),
PacketLayer
=
Protocol
:
new
(),
PacketLayer
=
Protocol
:
new
(),
Codec
=
mtp_codec
:
new
(
mtp_obfuscated
,
CryptoLayer
,
Codec
2
=
mtp_codec
:
replace
(
crypto
,
mtp_obfuscated
,
CryptoLayer
,
Codec1
)
,
Protocol
,
PacketLayer
,
false
,
undefined
,
25
*
1024
*
1024
),
Codec3
=
mtp_codec
:
replace
(
packet
,
Protocol
,
PacketLayer
,
Codec2
),
#client
{
sock
=
Sock
,
#client
{
sock
=
Sock
,
codec
=
Codec
}.
codec
=
Codec
3
}.
send
(
Data
,
#client
{
sock
=
Sock
,
codec
=
Codec
}
=
Client
)
->
send
(
Data
,
#client
{
sock
=
Sock
,
codec
=
Codec
}
=
Client
)
->
{
Enc
,
Codec1
}
=
mtp_codec
:
encode_packet
(
Data
,
Codec
),
{
Enc
,
Codec1
}
=
mtp_codec
:
encode_packet
(
Data
,
Codec
),
...
...
test/prop_mtp_statefull.erl
View file @
30f7e6b9
...
@@ -46,7 +46,9 @@ command(#st{open = [], ever_opened = EO}) ->
...
@@ -46,7 +46,9 @@ command(#st{open = [], ever_opened = EO}) ->
command
(
#st
{
open
=
L
,
ever_opened
=
EO
})
->
command
(
#st
{
open
=
L
,
ever_opened
=
EO
})
->
proper_types
:
frequency
(
proper_types
:
frequency
(
[
[
{
1
,
{
call
,
?
MODULE
,
connect
,
[
EO
,
mtp_prop_gen
:
codec
()]}},
{
1
,
{
call
,
?
MODULE
,
connect
,
[
EO
,
proper_types
:
oneof
(
[
mtp_prop_gen
:
codec
(),
{
mtp_fake_tls
,
<<
"en.wikipedia.org"
>>
}])]}},
{
5
,
{
call
,
?
MODULE
,
echo_packet
,
[
proper_types
:
oneof
(
L
),
proper_types
:
binary
()]}},
{
5
,
{
call
,
?
MODULE
,
echo_packet
,
[
proper_types
:
oneof
(
L
),
proper_types
:
binary
()]}},
{
2
,
{
call
,
?
MODULE
,
close
,
[
proper_types
:
oneof
(
L
)]}},
{
2
,
{
call
,
?
MODULE
,
close
,
[
proper_types
:
oneof
(
L
)]}},
{
2
,
{
call
,
?
MODULE
,
ask_for_close
,
[
proper_types
:
oneof
(
L
)]}}
{
2
,
{
call
,
?
MODULE
,
ask_for_close
,
[
proper_types
:
oneof
(
L
)]}}
...
@@ -108,8 +110,9 @@ run_cmds(Cmds) ->
...
@@ -108,8 +110,9 @@ run_cmds(Cmds) ->
?
WHENFAIL
(
io
:
format
(
"History:
~p
\n
"
?
WHENFAIL
(
io
:
format
(
"History:
~p
\n
"
"State:
~w
\n
"
"State:
~w
\n
"
"ServerState:
~p
\n
"
"ServerState:
~p
\n
"
"Metrics:
~p
\n
"
"Result:
~p
\n
"
,
"Result:
~p
\n
"
,
[
History
,
State
,
ServerState
,
Result
]),
[
History
,
State
,
ServerState
,
Metrics
,
Result
]),
proper
:
conjunction
(
proper
:
conjunction
(
[{
state_ok
,
check_state
(
State
,
ServerState
,
Metrics
,
ShimDump
)},
[{
state_ok
,
check_state
(
State
,
ServerState
,
Metrics
,
ShimDump
)},
{
result_ok
,
Result
=:=
ok
}])).
{
result_ok
,
Result
=:=
ok
}])).
...
...
test/single_dc_SUITE.erl
View file @
30f7e6b9
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
-
export
([
echo_secure_case
/
1
,
-
export
([
echo_secure_case
/
1
,
echo_abridged_many_packets_case
/
1
,
echo_abridged_many_packets_case
/
1
,
echo_tls_case
/
1
,
packet_too_large_case
/
1
,
packet_too_large_case
/
1
,
downstream_size_backpressure_case
/
1
,
downstream_size_backpressure_case
/
1
,
downstream_qlen_backpressure_case
/
1
,
downstream_qlen_backpressure_case
/
1
,
...
@@ -117,6 +118,24 @@ echo_abridged_many_packets_case(Cfg) when is_list(Cfg) ->
...
@@ -117,6 +118,24 @@ echo_abridged_many_packets_case(Cfg) when is_list(Cfg) ->
[
upstream_to_downstream
])).
[
upstream_to_downstream
])).
%% @doc tests that it's possible to connect and communicate using fake-tls protocol
echo_tls_case
({
pre
,
Cfg
})
->
setup_single
(
?
FUNCTION_NAME
,
10000
+
?
LINE
,
#
{},
Cfg
);
echo_tls_case
({
post
,
Cfg
})
->
stop_single
(
Cfg
);
echo_tls_case
(
Cfg
)
when
is_list
(
Cfg
)
->
DcId
=
?
config
(
dc_id
,
Cfg
),
Host
=
?
config
(
mtp_host
,
Cfg
),
Port
=
?
config
(
mtp_port
,
Cfg
),
Secret
=
?
config
(
mtp_secret
,
Cfg
),
Cli0
=
mtp_test_client
:
connect
(
Host
,
Port
,
Secret
,
DcId
,
{
mtp_fake_tls
,
<<
"example.com"
>>
}),
Data
=
crypto
:
strong_rand_bytes
(
64
),
Cli1
=
mtp_test_client
:
send
(
Data
,
Cli0
),
{
ok
,
Packet
,
Cli2
}
=
mtp_test_client
:
recv_packet
(
Cli1
,
1000
),
ok
=
mtp_test_client
:
close
(
Cli2
),
?
assertEqual
(
Data
,
Packet
).
%% @doc test that client trying to send too big packets will be force-disconnected
%% @doc test that client trying to send too big packets will be force-disconnected
packet_too_large_case
({
pre
,
Cfg
})
->
packet_too_large_case
({
pre
,
Cfg
})
->
setup_single
(
?
FUNCTION_NAME
,
10000
+
?
LINE
,
#
{},
Cfg
);
setup_single
(
?
FUNCTION_NAME
,
10000
+
?
LINE
,
#
{},
Cfg
);
...
...
test/test-sys.config
View file @
30f7e6b9
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
{
listen_ip
,
"127.0.0.1"
},
{
listen_ip
,
"127.0.0.1"
},
{
num_acceptors
,
2
},
{
num_acceptors
,
2
},
{
init_dc_connections
,
1
},
{
init_dc_connections
,
1
},
{
tls_allowed_domains
,
any
},
{
metric_backend
,
mtp_test_metric
}
{
metric_backend
,
mtp_test_metric
}
]},
]},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment