Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
tg
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
tg
Commits
923845d6
Commit
923845d6
authored
Nov 04, 2013
by
vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Partial support for encrypted chats.
parent
9dd3627a
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1072 additions
and
223 deletions
+1072
-223
interface.c
interface.c
+64
-38
interface.h
interface.h
+1
-1
loop.c
loop.c
+155
-1
loop.h
loop.h
+2
-0
main.c
main.c
+20
-0
mtproto-client.c
mtproto-client.c
+46
-8
mtproto-client.h
mtproto-client.h
+1
-0
mtproto-common.c
mtproto-common.c
+3
-0
mtproto-common.h
mtproto-common.h
+6
-2
net.h
net.h
+4
-1
queries.c
queries.c
+457
-13
queries.h
queries.h
+3
-0
structures.c
structures.c
+298
-116
structures.h
structures.h
+12
-43
No files found.
interface.c
View file @
923845d6
...
@@ -48,9 +48,8 @@ long long cur_downloading_bytes;
...
@@ -48,9 +48,8 @@ long long cur_downloading_bytes;
long
long
cur_downloaded_bytes
;
long
long
cur_downloaded_bytes
;
char
*
line_ptr
;
char
*
line_ptr
;
extern
int
user_num
;
extern
int
chat_num
;
extern
peer_t
*
Peers
[];
extern
peer_t
*
Peers
[];
extern
int
peer_num
;
int
is_same_word
(
const
char
*
s
,
size_t
l
,
const
char
*
word
)
{
int
is_same_word
(
const
char
*
s
,
size_t
l
,
const
char
*
word
)
{
return
s
&&
word
&&
strlen
(
word
)
==
l
&&
!
memcmp
(
s
,
word
,
l
);
return
s
&&
word
&&
strlen
(
word
)
==
l
&&
!
memcmp
(
s
,
word
,
l
);
...
@@ -106,10 +105,10 @@ peer_id_t next_token_user (void) {
...
@@ -106,10 +105,10 @@ peer_id_t next_token_user (void) {
}
}
int
index
=
0
;
int
index
=
0
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_USER
))
{
while
(
index
<
peer
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_USER
))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
return
Peers
[
index
]
->
id
;
return
Peers
[
index
]
->
id
;
}
else
{
}
else
{
return
PEER_NOT_FOUND
;
return
PEER_NOT_FOUND
;
...
@@ -130,10 +129,10 @@ peer_id_t next_token_chat (void) {
...
@@ -130,10 +129,10 @@ peer_id_t next_token_chat (void) {
}
}
int
index
=
0
;
int
index
=
0
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_CHAT
))
{
while
(
index
<
peer
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_CHAT
))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
return
Peers
[
index
]
->
id
;
return
Peers
[
index
]
->
id
;
}
else
{
}
else
{
return
PEER_NOT_FOUND
;
return
PEER_NOT_FOUND
;
...
@@ -161,10 +160,10 @@ peer_id_t next_token_peer (void) {
...
@@ -161,10 +160,10 @@ peer_id_t next_token_peer (void) {
}
}
int
index
=
0
;
int
index
=
0
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)))
{
while
(
index
<
peer
_num
&&
(
!
is_same_word
(
s
,
l
,
Peers
[
index
]
->
print_name
)))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
return
Peers
[
index
]
->
id
;
return
Peers
[
index
]
->
id
;
}
else
{
}
else
{
return
PEER_NOT_FOUND
;
return
PEER_NOT_FOUND
;
...
@@ -232,6 +231,7 @@ char *commands[] = {
...
@@ -232,6 +231,7 @@ char *commands[] = {
"rename_contact"
,
"rename_contact"
,
"show_license"
,
"show_license"
,
"search"
,
"search"
,
"mark_read"
,
0
};
0
};
int
commands_flags
[]
=
{
int
commands_flags
[]
=
{
...
@@ -258,6 +258,7 @@ int commands_flags[] = {
...
@@ -258,6 +258,7 @@ int commands_flags[] = {
071
,
071
,
07
,
07
,
072
,
072
,
072
,
};
};
int
get_complete_mode
(
void
)
{
int
get_complete_mode
(
void
)
{
...
@@ -297,10 +298,10 @@ int get_complete_mode (void) {
...
@@ -297,10 +298,10 @@ int get_complete_mode (void) {
int
complete_user_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
int
complete_user_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
index
++
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_USER
))
{
while
(
index
<
peer
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_USER
))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
return
index
;
return
index
;
}
else
{
}
else
{
...
@@ -310,10 +311,10 @@ int complete_user_list (int index, const char *text, int len, char **R) {
...
@@ -310,10 +311,10 @@ int complete_user_list (int index, const char *text, int len, char **R) {
int
complete_chat_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
int
complete_chat_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
index
++
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_CHAT
))
{
while
(
index
<
peer
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)
||
get_peer_type
(
Peers
[
index
]
->
id
)
!=
PEER_CHAT
))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
return
index
;
return
index
;
}
else
{
}
else
{
...
@@ -323,10 +324,10 @@ int complete_chat_list (int index, const char *text, int len, char **R) {
...
@@ -323,10 +324,10 @@ int complete_chat_list (int index, const char *text, int len, char **R) {
int
complete_user_chat_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
int
complete_user_chat_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
index
++
;
while
(
index
<
user_num
+
chat
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)))
{
while
(
index
<
peer
_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)))
{
index
++
;
index
++
;
}
}
if
(
index
<
user_num
+
chat
_num
)
{
if
(
index
<
peer
_num
)
{
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
return
index
;
return
index
;
}
else
{
}
else
{
...
@@ -663,6 +664,8 @@ void interpreter (char *line UU) {
...
@@ -663,6 +664,8 @@ void interpreter (char *line UU) {
"load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir
\n
"
"load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir
\n
"
"view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer
\n
"
"view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer
\n
"
"show_license - prints contents of GPLv2
\n
"
"show_license - prints contents of GPLv2
\n
"
"search <peer> pattern - searches pattern in messages with peer
\n
"
"mark_read <peer> - mark read all received messages with peer
\n
"
);
);
pop_color
();
pop_color
();
rl_on_new_line
();
rl_on_new_line
();
...
@@ -685,6 +688,9 @@ void interpreter (char *line UU) {
...
@@ -685,6 +688,9 @@ void interpreter (char *line UU) {
RET
;
RET
;
}
}
do_msg_search
(
id
,
from
,
to
,
limit
,
s
);
do_msg_search
(
id
,
from
,
to
,
limit
,
s
);
}
else
if
(
IS_WORD
(
"mark_read"
))
{
GET_PEER
;
do_mark_read
(
id
);
}
}
#undef IS_WORD
#undef IS_WORD
#undef RET
#undef RET
...
@@ -796,30 +802,6 @@ void logprintf (const char *format, ...) {
...
@@ -796,30 +802,6 @@ void logprintf (const char *format, ...) {
}
}
}
}
const
char
*
message_media_type_str
(
struct
message_media
*
M
)
{
static
char
buf
[
1000
];
switch
(
M
->
type
)
{
case
CODE_message_media_empty
:
return
""
;
case
CODE_message_media_photo
:
return
"[photo]"
;
case
CODE_message_media_video
:
return
"[video]"
;
case
CODE_message_media_geo
:
sprintf
(
buf
,
"[geo] https://maps.google.com/maps?ll=%.6lf,%.6lf"
,
M
->
geo
.
latitude
,
M
->
geo
.
longitude
);
return
buf
;
case
CODE_message_media_contact
:
snprintf
(
buf
,
999
,
"[contact] "
COLOR_RED
"%s %s"
COLOR_NORMAL
" %s"
,
M
->
first_name
,
M
->
last_name
,
M
->
phone
);
return
buf
;
case
CODE_message_media_unsupported
:
return
"[unsupported]"
;
default:
assert
(
0
);
return
""
;
}
}
int
color_stack_pos
;
int
color_stack_pos
;
const
char
*
color_stack
[
10
];
const
char
*
color_stack
[
10
];
...
@@ -853,6 +835,12 @@ void print_media (struct message_media *M) {
...
@@ -853,6 +835,12 @@ void print_media (struct message_media *M) {
case
CODE_message_media_video
:
case
CODE_message_media_video
:
printf
(
"[video]"
);
printf
(
"[video]"
);
return
;
return
;
case
CODE_decrypted_message_media_photo
:
printf
(
"[photo]"
);
return
;
case
CODE_decrypted_message_media_video
:
printf
(
"[video]"
);
return
;
case
CODE_message_media_geo
:
case
CODE_message_media_geo
:
printf
(
"[geo] https://maps.google.com/?q=%.6lf,%.6lf"
,
M
->
geo
.
latitude
,
M
->
geo
.
longitude
);
printf
(
"[geo] https://maps.google.com/?q=%.6lf,%.6lf"
,
M
->
geo
.
latitude
,
M
->
geo
.
longitude
);
return
;
return
;
...
@@ -1009,6 +997,9 @@ peer_id_t last_from_id;
...
@@ -1009,6 +997,9 @@ peer_id_t last_from_id;
peer_id_t
last_to_id
;
peer_id_t
last_to_id
;
void
print_message
(
struct
message
*
M
)
{
void
print_message
(
struct
message
*
M
)
{
if
(
M
->
flags
&
(
FLAG_EMPTY
|
FLAG_DELETED
))
{
return
;
}
if
(
M
->
service
)
{
if
(
M
->
service
)
{
print_service_message
(
M
);
print_service_message
(
M
);
return
;
return
;
...
@@ -1050,7 +1041,42 @@ void print_message (struct message *M) {
...
@@ -1050,7 +1041,42 @@ void print_message (struct message *M) {
printf
(
" »»» "
);
printf
(
" »»» "
);
}
}
}
}
}
else
if
(
get_peer_type
(
M
->
to_id
)
==
PEER_ENCR_CHAT
)
{
peer_t
*
P
=
user_chat_get
(
M
->
to_id
);
assert
(
P
);
if
(
M
->
out
)
{
push_color
(
COLOR_GREEN
);
if
(
msg_num_mode
)
{
printf
(
"%lld "
,
M
->
id
);
}
print_date
(
M
->
date
);
printf
(
" "
);
push_color
(
COLOR_CYAN
);
printf
(
" %s"
,
P
->
print_name
);
pop_color
();
if
(
M
->
unread
)
{
printf
(
" <<< "
);
}
else
{
printf
(
" ««« "
);
}
}
else
{
push_color
(
COLOR_BLUE
);
if
(
msg_num_mode
)
{
printf
(
"%lld "
,
M
->
id
);
}
print_date
(
M
->
date
);
push_color
(
COLOR_CYAN
);
printf
(
" %s"
,
P
->
print_name
);
pop_color
();
if
(
M
->
unread
)
{
printf
(
" >>> "
);
}
else
{
printf
(
" »»» "
);
}
}
}
else
{
}
else
{
assert
(
get_peer_type
(
M
->
to_id
)
==
PEER_CHAT
);
push_color
(
COLOR_MAGENTA
);
push_color
(
COLOR_MAGENTA
);
if
(
msg_num_mode
)
{
if
(
msg_num_mode
)
{
printf
(
"%lld "
,
M
->
id
);
printf
(
"%lld "
,
M
->
id
);
...
...
interface.h
View file @
923845d6
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
#define COLOR_YELLOW "\033[33;1m"
#define COLOR_YELLOW "\033[33;1m"
#define COLOR_BLUE "\033[34;1m"
#define COLOR_BLUE "\033[34;1m"
#define COLOR_MAGENTA "\033[35;1m"
#define COLOR_MAGENTA "\033[35;1m"
#define COLOR_CYAN "\033[36;1m"
char
*
get_default_prompt
(
void
);
char
*
get_default_prompt
(
void
);
char
*
complete_none
(
const
char
*
text
,
int
state
);
char
*
complete_none
(
const
char
*
text
,
int
state
);
...
...
loop.c
View file @
923845d6
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#include "mtproto-common.h"
#include "mtproto-common.h"
#include "queries.h"
#include "queries.h"
#include "telegram.h"
#include "telegram.h"
#include "loop.h"
extern
char
*
default_username
;
extern
char
*
default_username
;
extern
char
*
auth_token
;
extern
char
*
auth_token
;
...
@@ -59,6 +60,7 @@ void net_loop (int flags, int (*is_end)(void)) {
...
@@ -59,6 +60,7 @@ void net_loop (int flags, int (*is_end)(void)) {
cc
++
;
cc
++
;
}
}
write_state_file
();
int
x
=
connections_make_poll_array
(
fds
+
cc
,
101
-
cc
)
+
cc
;
int
x
=
connections_make_poll_array
(
fds
+
cc
,
101
-
cc
)
+
cc
;
double
timer
=
next_timer_in
();
double
timer
=
next_timer_in
();
if
(
timer
>
1000
)
{
timer
=
1000
;
}
if
(
timer
>
1000
)
{
timer
=
1000
;
}
...
@@ -116,6 +118,8 @@ struct dc *DC_working;
...
@@ -116,6 +118,8 @@ struct dc *DC_working;
int
dc_working_num
;
int
dc_working_num
;
int
auth_state
;
int
auth_state
;
char
*
get_auth_key_filename
(
void
);
char
*
get_auth_key_filename
(
void
);
char
*
get_state_filename
(
void
);
char
*
get_secret_chat_filename
(
void
);
int
zero
[
512
];
int
zero
[
512
];
...
@@ -231,11 +235,157 @@ void read_auth_file (void) {
...
@@ -231,11 +235,157 @@ void read_auth_file (void) {
}
}
}
}
int
pts
,
qts
,
seq
,
last_date
;
void
read_state_file
(
void
)
{
int
state_file_fd
=
open
(
get_state_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
state_file_fd
<
0
)
{
return
;
}
int
version
,
magic
;
if
(
read
(
state_file_fd
,
&
magic
,
4
)
<
4
)
{
close
(
state_file_fd
);
return
;
}
if
(
magic
!=
(
int
)
STATE_FILE_MAGIC
)
{
close
(
state_file_fd
);
return
;
}
if
(
read
(
state_file_fd
,
&
version
,
4
)
<
4
)
{
close
(
state_file_fd
);
return
;
}
assert
(
version
>=
0
);
int
x
[
4
];
if
(
read
(
state_file_fd
,
x
,
16
)
<
16
)
{
close
(
state_file_fd
);
return
;
}
pts
=
x
[
0
];
qts
=
x
[
1
];
seq
=
x
[
2
];
last_date
=
x
[
3
];
close
(
state_file_fd
);
}
void
write_state_file
(
void
)
{
static
int
wseq
;
static
int
wpts
;
static
int
wqts
;
static
int
wdate
;
if
(
wseq
>=
seq
&&
wpts
>=
pts
&&
wqts
>=
qts
&&
wdate
>=
last_date
)
{
return
;
}
int
state_file_fd
=
open
(
get_state_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
state_file_fd
<
0
)
{
return
;
}
int
x
[
6
];
x
[
0
]
=
STATE_FILE_MAGIC
;
x
[
1
]
=
0
;
x
[
2
]
=
pts
;
x
[
3
]
=
qts
;
x
[
4
]
=
seq
;
x
[
5
]
=
last_date
;
assert
(
write
(
state_file_fd
,
x
,
24
)
==
24
);
close
(
state_file_fd
);
wseq
=
seq
;
wpts
=
pts
;
wqts
=
qts
;
wdate
=
last_date
;
}
extern
peer_t
*
Peers
[];
extern
int
peer_num
;
void
read_secret_chat_file
(
void
)
{
int
fd
=
open
(
get_secret_chat_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
fd
<
0
)
{
return
;
}
int
x
[
2
];
if
(
read
(
fd
,
x
,
8
)
<
8
)
{
close
(
fd
);
return
;
}
if
(
x
[
0
]
!=
(
int
)
SECRET_CHAT_FILE_MAGIC
)
{
close
(
fd
);
return
;
}
int
version
=
x
[
1
];
assert
(
version
>=
0
);
int
cc
;
assert
(
read
(
fd
,
&
cc
,
4
)
==
4
);
int
i
;
for
(
i
=
0
;
i
<
cc
;
i
++
)
{
peer_t
*
P
=
malloc
(
sizeof
(
*
P
));
memset
(
P
,
0
,
sizeof
(
*
P
));
struct
secret_chat
*
E
=
&
P
->
encr_chat
;
int
t
;
assert
(
read
(
fd
,
&
t
,
4
)
==
4
);
P
->
id
=
MK_ENCR_CHAT
(
t
);
assert
(
read
(
fd
,
&
P
->
flags
,
4
)
==
4
);
assert
(
read
(
fd
,
&
t
,
4
)
==
4
);
assert
(
t
>
0
);
P
->
print_name
=
malloc
(
t
+
1
);
assert
(
read
(
fd
,
P
->
print_name
,
t
)
==
t
);
P
->
print_name
[
t
]
=
0
;
assert
(
read
(
fd
,
&
E
->
state
,
4
)
==
4
);
assert
(
read
(
fd
,
&
E
->
user_id
,
4
)
==
4
);
assert
(
read
(
fd
,
&
E
->
admin_id
,
4
)
==
4
);
assert
(
read
(
fd
,
&
E
->
ttl
,
4
)
==
4
);
assert
(
read
(
fd
,
&
E
->
access_hash
,
8
)
==
8
);
if
(
E
->
state
!=
sc_waiting
)
{
E
->
g_key
=
malloc
(
256
);
assert
(
read
(
fd
,
E
->
g_key
,
256
)
==
256
);
}
E
->
nonce
=
malloc
(
256
);
assert
(
read
(
fd
,
E
->
nonce
,
256
)
==
256
);
assert
(
read
(
fd
,
E
->
key
,
256
)
==
256
);
assert
(
read
(
fd
,
&
E
->
key_fingerprint
,
8
)
==
8
);
insert_encrypted_chat
(
P
);
}
close
(
fd
);
}
void
write_secret_chat_file
(
void
)
{
int
fd
=
open
(
get_secret_chat_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
fd
<
0
)
{
return
;
}
int
x
[
2
];
x
[
0
]
=
SECRET_CHAT_FILE_MAGIC
;
x
[
1
]
=
0
;
assert
(
write
(
fd
,
x
,
8
)
==
8
);
int
i
;
int
cc
=
0
;
for
(
i
=
0
;
i
<
peer_num
;
i
++
)
if
(
get_peer_type
(
Peers
[
i
]
->
id
)
==
PEER_ENCR_CHAT
)
{
if
(
Peers
[
i
]
->
encr_chat
.
state
!=
sc_none
&&
Peers
[
i
]
->
encr_chat
.
state
!=
sc_deleted
)
{
cc
++
;
}
}
assert
(
write
(
fd
,
&
cc
,
4
)
==
4
);
for
(
i
=
0
;
i
<
peer_num
;
i
++
)
if
(
get_peer_type
(
Peers
[
i
]
->
id
)
==
PEER_ENCR_CHAT
)
{
if
(
Peers
[
i
]
->
encr_chat
.
state
!=
sc_none
&&
Peers
[
i
]
->
encr_chat
.
state
!=
sc_deleted
)
{
int
t
=
get_peer_id
(
Peers
[
i
]
->
id
);
assert
(
write
(
fd
,
&
t
,
4
)
==
4
);
t
=
Peers
[
i
]
->
flags
;
assert
(
write
(
fd
,
&
t
,
4
)
==
4
);
t
=
strlen
(
Peers
[
i
]
->
print_name
);
assert
(
write
(
fd
,
&
t
,
4
)
==
4
);
assert
(
write
(
fd
,
Peers
[
i
]
->
print_name
,
t
)
==
t
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
state
,
4
)
==
4
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
user_id
,
4
)
==
4
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
admin_id
,
4
)
==
4
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
ttl
,
4
)
==
4
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
access_hash
,
8
)
==
8
);
if
(
Peers
[
i
]
->
encr_chat
.
state
!=
sc_waiting
)
{
assert
(
write
(
fd
,
Peers
[
i
]
->
encr_chat
.
g_key
,
256
)
==
256
);
}
assert
(
write
(
fd
,
Peers
[
i
]
->
encr_chat
.
nonce
,
256
)
==
256
);
assert
(
write
(
fd
,
Peers
[
i
]
->
encr_chat
.
key
,
256
)
==
256
);
assert
(
write
(
fd
,
&
Peers
[
i
]
->
encr_chat
.
key_fingerprint
,
8
)
==
8
);
}
}
close
(
fd
);
}
extern
int
max_chat_size
;
extern
int
max_chat_size
;
int
mcs
(
void
)
{
int
mcs
(
void
)
{
return
max_chat_size
;
return
max_chat_size
;
}
}
extern
int
difference_got
;
int
dgot
(
void
)
{
return
!
difference_got
;
}
int
readline_active
;
int
readline_active
;
int
new_dc_num
;
int
new_dc_num
;
int
loop
(
void
)
{
int
loop
(
void
)
{
...
@@ -368,7 +518,11 @@ int loop (void) {
...
@@ -368,7 +518,11 @@ int loop (void) {
rl_attempted_completion_function
=
(
CPPFunction
*
)
complete_text
;
rl_attempted_completion_function
=
(
CPPFunction
*
)
complete_text
;
rl_completion_entry_function
=
complete_none
;
rl_completion_entry_function
=
complete_none
;
do_get_dialog_list_ex
();
read_state_file
();
read_secret_chat_file
();
do_get_difference
();
net_loop
(
0
,
dgot
);
do_get_dialog_list
();
return
main_loop
();
return
main_loop
();
}
}
...
...
loop.h
View file @
923845d6
...
@@ -21,4 +21,6 @@
...
@@ -21,4 +21,6 @@
int
loop
(
void
);
int
loop
(
void
);
void
net_loop
(
int
flags
,
int
(
*
end
)(
void
));
void
net_loop
(
int
flags
,
int
(
*
end
)(
void
));
void
write_auth_file
(
void
);
void
write_auth_file
(
void
);
void
write_state_file
(
void
);
void
write_secret_chat_file
(
void
);
#endif
#endif
main.c
View file @
923845d6
...
@@ -41,6 +41,8 @@
...
@@ -41,6 +41,8 @@
#define CONFIG_DIRECTORY ".telegram/"
#define CONFIG_DIRECTORY ".telegram/"
#define CONFIG_FILE CONFIG_DIRECTORY "config"
#define CONFIG_FILE CONFIG_DIRECTORY "config"
#define AUTH_KEY_FILE CONFIG_DIRECTORY "auth"
#define AUTH_KEY_FILE CONFIG_DIRECTORY "auth"
#define STATE_FILE CONFIG_DIRECTORY "state"
#define SECRET_CHAT_FILE CONFIG_DIRECTORY "secret"
#define DOWNLOADS_DIRECTORY "downloads/"
#define DOWNLOADS_DIRECTORY "downloads/"
#define CONFIG_DIRECTORY_MODE 0700
#define CONFIG_DIRECTORY_MODE 0700
...
@@ -130,6 +132,24 @@ char *get_auth_key_filename (void) {
...
@@ -130,6 +132,24 @@ char *get_auth_key_filename (void) {
return
auth_key_filename
;
return
auth_key_filename
;
}
}
char
*
get_state_filename
(
void
)
{
char
*
state_filename
;
int
length
=
strlen
(
get_home_directory
())
+
strlen
(
STATE_FILE
)
+
2
;
state_filename
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
sprintf
(
state_filename
,
"%s/"
STATE_FILE
,
get_home_directory
());
return
state_filename
;
}
char
*
get_secret_chat_filename
(
void
)
{
char
*
secret_chat_filename
;
int
length
=
strlen
(
get_home_directory
())
+
strlen
(
SECRET_CHAT_FILE
)
+
2
;
secret_chat_filename
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
sprintf
(
secret_chat_filename
,
"%s/"
SECRET_CHAT_FILE
,
get_home_directory
());
return
secret_chat_filename
;
}
char
*
get_downloads_directory
(
void
)
char
*
get_downloads_directory
(
void
)
{
{
char
*
downloads_directory
;
char
*
downloads_directory
;
...
...
mtproto-client.c
View file @
923845d6
...
@@ -637,14 +637,18 @@ int unread_messages;
...
@@ -637,14 +637,18 @@ int unread_messages;
int
our_id
;
int
our_id
;
int
pts
;
int
pts
;
int
qts
;
int
qts
;
int
last_date
;
int
seq
;
void
fetch_pts
(
void
)
{
void
fetch_pts
(
void
)
{
int
p
=
fetch_int
();
int
p
=
fetch_int
();
if
(
p
<=
pts
)
{
return
;
}
if
(
p
!=
pts
+
1
)
{
if
(
p
!=
pts
+
1
)
{
if
(
pts
)
{
if
(
pts
)
{
logprintf
(
"Hole in pts p = %d, pts = %d
\n
"
,
p
,
pts
);
//
logprintf ("Hole in pts p = %d, pts = %d\n", p, pts);
// get difference should be here
// get difference should be here
pts
=
p
;
}
else
{
}
else
{
pts
=
p
;
pts
=
p
;
}
}
...
@@ -655,10 +659,12 @@ void fetch_pts (void) {
...
@@ -655,10 +659,12 @@ void fetch_pts (void) {
void
fetch_qts
(
void
)
{
void
fetch_qts
(
void
)
{
int
p
=
fetch_int
();
int
p
=
fetch_int
();
if
(
p
<=
qts
)
{
return
;
}
if
(
p
!=
qts
+
1
)
{
if
(
p
!=
qts
+
1
)
{
if
(
qts
)
{
if
(
qts
)
{
logprintf
(
"Hole in qts
\n
"
);
//
logprintf ("Hole in qts\n");
// get difference should be here
// get difference should be here
qts
=
p
;
}
else
{
}
else
{
qts
=
p
;
qts
=
p
;
}
}
...
@@ -667,6 +673,24 @@ void fetch_qts (void) {
...
@@ -667,6 +673,24 @@ void fetch_qts (void) {
}
}
}
}
void
fetch_date
(
void
)
{
int
p
=
fetch_int
();
if
(
p
>
last_date
)
{
last_date
=
p
;
}
}
void
fetch_seq
(
void
)
{
int
x
=
fetch_int
();
if
(
x
>
seq
+
1
)
{
logprintf
(
"Hole in seq: seq = %d, x = %d
\n
"
,
seq
,
x
);
//do_get_difference ();
seq
=
x
;
}
else
if
(
x
>=
seq
+
1
)
{
seq
=
x
;
}
}
void
work_update
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
void
work_update
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
unsigned
op
=
fetch_int
();
unsigned
op
=
fetch_int
();
switch
(
op
)
{
switch
(
op
)
{
...
@@ -993,9 +1017,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
...
@@ -993,9 +1017,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf
(
" is now in deleted state
\n
"
);
printf
(
" is now in deleted state
\n
"
);
break
;
break
;
}
}
/*if (E->state == state_requested) {
pop_color
();
print_end
();
if
(
E
->
state
==
sc_request
)
{
do_accept_encr_chat_request
(
E
);
do_accept_encr_chat_request
(
E
);
}
*/
}
fetch_int
();
// date
fetch_int
();
// date
}
}
break
;
break
;
...
@@ -1041,7 +1067,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
...
@@ -1041,7 +1067,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
void
work_update_short
(
struct
connection
*
c
,
long
long
msg_id
)
{
void
work_update_short
(
struct
connection
*
c
,
long
long
msg_id
)
{
assert
(
fetch_int
()
==
CODE_update_short
);
assert
(
fetch_int
()
==
CODE_update_short
);
work_update
(
c
,
msg_id
);
work_update
(
c
,
msg_id
);
fetch_
int
();
// date
fetch_
date
();
}
}
void
work_updates
(
struct
connection
*
c
,
long
long
msg_id
)
{
void
work_updates
(
struct
connection
*
c
,
long
long
msg_id
)
{
...
@@ -1062,9 +1088,8 @@ void work_updates (struct connection *c, long long msg_id) {
...
@@ -1062,9 +1088,8 @@ void work_updates (struct connection *c, long long msg_id) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_chat
();
fetch_alloc_chat
();
}
}
fetch_int
();
// date
fetch_date
();
// date
fetch_int
();
// seq
fetch_seq
();
// seq
}
}
void
work_update_short_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
void
work_update_short_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
...
@@ -1073,6 +1098,9 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) {
...
@@ -1073,6 +1098,9 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) {
unread_messages
++
;
unread_messages
++
;
print_message
(
M
);
print_message
(
M
);
update_prompt
();
update_prompt
();
if
(
M
->
date
>
last_date
)
{
last_date
=
M
->
date
;
}
}
}
void
work_update_short_chat_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
void
work_update_short_chat_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
...
@@ -1081,6 +1109,9 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
...
@@ -1081,6 +1109,9 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
unread_messages
++
;
unread_messages
++
;
print_message
(
M
);
print_message
(
M
);
update_prompt
();
update_prompt
();
if
(
M
->
date
>
last_date
)
{
last_date
=
M
->
date
;
}
}
}
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
...
@@ -1211,6 +1242,10 @@ void work_detained_info (struct connection *c UU, long long msg_id UU) {
...
@@ -1211,6 +1242,10 @@ void work_detained_info (struct connection *c UU, long long msg_id UU) {
fetch_int
();
// status
fetch_int
();
// status
}
}
void
work_updates_to_long
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_too_long
);
do_get_difference
();
}
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
if
(
verbosity
>=
5
)
{
if
(
verbosity
>=
5
)
{
logprintf
(
"rpc_execute_answer: fd=%d
\n
"
,
c
->
fd
);
logprintf
(
"rpc_execute_answer: fd=%d
\n
"
,
c
->
fd
);
...
@@ -1254,6 +1289,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
...
@@ -1254,6 +1289,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
case
CODE_msg_detained_info
:
case
CODE_msg_detained_info
:
work_detained_info
(
c
,
msg_id
);
work_detained_info
(
c
,
msg_id
);
return
;
return
;
case
CODE_updates_too_long
:
work_updates_to_long
(
c
,
msg_id
);
return
;
}
}
logprintf
(
"Unknown message:
\n
"
);
logprintf
(
"Unknown message:
\n
"
);
hexdump_in
();
hexdump_in
();
...
...
mtproto-client.h
View file @
923845d6
...
@@ -23,4 +23,5 @@
...
@@ -23,4 +23,5 @@
void
on_start
(
void
);
void
on_start
(
void
);
long
long
encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
);
long
long
encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
);
void
dc_authorize
(
struct
dc
*
DC
);
void
dc_authorize
(
struct
dc
*
DC
);
void
work_update
(
struct
connection
*
c
,
long
long
msg_id
);
#endif
#endif
mtproto-common.c
View file @
923845d6
...
@@ -37,6 +37,9 @@
...
@@ -37,6 +37,9 @@
#include "mtproto-common.h"
#include "mtproto-common.h"
#include "interface.h"
#include "interface.h"
int
__packet_buffer
[
PACKET_BUFFER_SIZE
],
*
packet_ptr
;
int
*
packet_buffer
=
__packet_buffer
+
16
;
long
long
rsa_encrypted_chunks
,
rsa_decrypted_chunks
;
long
long
rsa_encrypted_chunks
,
rsa_decrypted_chunks
;
BN_CTX
*
BN_ctx
;
BN_CTX
*
BN_ctx
;
...
...
mtproto-common.h
View file @
923845d6
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
#define MAX_MESSAGE_INTS 1048576
#define MAX_MESSAGE_INTS 1048576
#define MAX_PROTO_MESSAGE_INTS 1048576
#define MAX_PROTO_MESSAGE_INTS 1048576
#define PACKET_BUFFER_SIZE (16384 * 100 + 16) // temp fix
#pragma pack(push,4)
#pragma pack(push,4)
struct
encrypted_message
{
struct
encrypted_message
{
// unencrypted header
// unencrypted header
...
@@ -219,8 +220,8 @@ void prng_seed (const char *password_filename, int password_length);
...
@@ -219,8 +220,8 @@ void prng_seed (const char *password_filename, int password_length);
int
serialize_bignum
(
BIGNUM
*
b
,
char
*
buffer
,
int
maxlen
);
int
serialize_bignum
(
BIGNUM
*
b
,
char
*
buffer
,
int
maxlen
);
long
long
compute_rsa_key_fingerprint
(
RSA
*
key
);
long
long
compute_rsa_key_fingerprint
(
RSA
*
key
);
#define PACKET_BUFFER_SIZE (16384 * 100) // temp fix
extern
int
*
packet_buffer
;
int
packet_buffer
[
PACKET_BUFFER_SIZE
],
*
packet_ptr
;
extern
int
*
packet_ptr
;
static
inline
void
out_ints
(
int
*
what
,
int
len
)
{
static
inline
void
out_ints
(
int
*
what
,
int
len
)
{
assert
(
packet_ptr
+
len
<=
packet_buffer
+
PACKET_BUFFER_SIZE
);
assert
(
packet_ptr
+
len
<=
packet_buffer
+
PACKET_BUFFER_SIZE
);
...
@@ -262,6 +263,9 @@ static inline void out_bignum (BIGNUM *n) {
...
@@ -262,6 +263,9 @@ static inline void out_bignum (BIGNUM *n) {
extern
int
*
in_ptr
,
*
in_end
;
extern
int
*
in_ptr
,
*
in_end
;
void
fetch_pts
(
void
);
void
fetch_pts
(
void
);
void
fetch_qts
(
void
);
void
fetch_date
(
void
);
void
fetch_seq
(
void
);
static
inline
int
prefetch_strlen
(
void
)
{
static
inline
int
prefetch_strlen
(
void
)
{
if
(
in_ptr
>=
in_end
)
{
if
(
in_ptr
>=
in_end
)
{
return
-
1
;
return
-
1
;
...
...
net.h
View file @
923845d6
...
@@ -26,7 +26,7 @@ struct dc;
...
@@ -26,7 +26,7 @@ struct dc;
//#define TG_SERVER "95.142.192.66"
//#define TG_SERVER "95.142.192.66"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define TG_APP_ID 2899
#define TG_BUILD "20
0
"
#define TG_BUILD "20
3
"
#define TG_VERSION "0.01-beta"
#define TG_VERSION "0.01-beta"
...
@@ -79,6 +79,9 @@ struct dc {
...
@@ -79,6 +79,9 @@ struct dc {
#define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb
#define DC_SERIALIZED_MAGIC_V2 0x94032abb
#define STATE_FILE_MAGIC 0x84217a0d
#define SECRET_CHAT_FILE_MAGIC 0xa9840add
struct
dc_serialized
{
struct
dc_serialized
{
int
magic
;
int
magic
;
int
port
;
int
port
;
...
...
queries.c
View file @
923845d6
...
@@ -37,6 +37,12 @@
...
@@ -37,6 +37,12 @@
#include "structures.h"
#include "structures.h"
#include "interface.h"
#include "interface.h"
#include "net.h"
#include "net.h"
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
#define sha1 SHA1
char
*
get_downloads_directory
(
void
);
char
*
get_downloads_directory
(
void
);
int
verbosity
;
int
verbosity
;
...
@@ -276,6 +282,8 @@ int new_dc_num;
...
@@ -276,6 +282,8 @@ int new_dc_num;
extern
struct
dc
*
DC_list
[];
extern
struct
dc
*
DC_list
[];
extern
struct
dc
*
DC_working
;
extern
struct
dc
*
DC_working
;
/* {{{ Get config */
int
help_get_config_on_answer
(
struct
query
*
q
UU
)
{
int
help_get_config_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_config
);
assert
(
fetch_int
()
==
CODE_config
);
fetch_int
();
fetch_int
();
...
@@ -323,7 +331,9 @@ void do_help_get_config (void) {
...
@@ -323,7 +331,9 @@ void do_help_get_config (void) {
out_int
(
CODE_help_get_config
);
out_int
(
CODE_help_get_config
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
);
}
}
/* }}} */
/* {{{ Send code */
char
*
phone_code_hash
;
char
*
phone_code_hash
;
int
send_code_on_answer
(
struct
query
*
q
UU
)
{
int
send_code_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_auth_sent_code
);
assert
(
fetch_int
()
==
CODE_auth_sent_code
);
...
@@ -407,8 +417,9 @@ void do_send_code (const char *user) {
...
@@ -407,8 +417,9 @@ void do_send_code (const char *user) {
net_loop
(
0
,
code_is_sent
);
net_loop
(
0
,
code_is_sent
);
assert
(
want_dc_num
==
-
1
);
assert
(
want_dc_num
==
-
1
);
}
}
/* }}} */
/* {{{ Check phone */
int
check_phone_result
;
int
check_phone_result
;
int
cr_f
(
void
)
{
int
cr_f
(
void
)
{
return
check_phone_result
>=
0
;
return
check_phone_result
>=
0
;
...
@@ -460,7 +471,9 @@ int do_auth_check_phone (const char *user) {
...
@@ -460,7 +471,9 @@ int do_auth_check_phone (const char *user) {
net_loop
(
0
,
cr_f
);
net_loop
(
0
,
cr_f
);
return
check_phone_result
;
return
check_phone_result
;
}
}
/* }}} */
/* {{{ Nearest DC */
int
nearest_dc_num
;
int
nearest_dc_num
;
int
nr_f
(
void
)
{
int
nr_f
(
void
)
{
return
nearest_dc_num
>=
0
;
return
nearest_dc_num
>=
0
;
...
@@ -497,7 +510,9 @@ int do_get_nearest_dc (void) {
...
@@ -497,7 +510,9 @@ int do_get_nearest_dc (void) {
net_loop
(
0
,
nr_f
);
net_loop
(
0
,
nr_f
);
return
nearest_dc_num
;
return
nearest_dc_num
;
}
}
/* }}} */
/* {{{ Sign in / Sign up */
int
sign_in_ok
;
int
sign_in_ok
;
int
sign_in_is_ok
(
void
)
{
int
sign_in_is_ok
(
void
)
{
return
sign_in_ok
;
return
sign_in_ok
;
...
@@ -554,7 +569,9 @@ int do_send_code_result_auth (const char *code, const char *first_name, const ch
...
@@ -554,7 +569,9 @@ int do_send_code_result_auth (const char *code, const char *first_name, const ch
net_loop
(
0
,
sign_in_is_ok
);
net_loop
(
0
,
sign_in_is_ok
);
return
sign_in_ok
;
return
sign_in_ok
;
}
}
/* }}} */
/* {{{ Get contacts */
extern
char
*
user_list
[];
extern
char
*
user_list
[];
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
...
@@ -612,18 +629,106 @@ void do_update_contact_list (void) {
...
@@ -612,18 +629,106 @@ void do_update_contact_list (void) {
out_string
(
""
);
out_string
(
""
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
);
}
}
/* }}} */
/* {{{ Encrypt decrypted */
int
*
encr_extra
;
int
*
encr_ptr
;
int
*
encr_end
;
char
*
encrypt_decrypted_message
(
struct
secret_chat
*
E
)
{
static
int
msg_key
[
4
];
static
unsigned
char
sha1a_buffer
[
20
];
static
unsigned
char
sha1b_buffer
[
20
];
static
unsigned
char
sha1c_buffer
[
20
];
static
unsigned
char
sha1d_buffer
[
20
];
int
x
=
*
(
encr_ptr
);
assert
(
x
>=
0
&&
!
(
x
&
3
));
sha1
((
void
*
)
encr_ptr
,
4
+
x
,
sha1a_buffer
);
memcpy
(
msg_key
,
sha1a_buffer
+
4
,
16
);
static
unsigned
char
buf
[
64
];
memcpy
(
buf
,
msg_key
,
16
);
memcpy
(
buf
+
16
,
E
->
key
,
32
);
sha1
(
buf
,
48
,
sha1a_buffer
);
memcpy
(
buf
,
E
->
key
+
8
,
16
);
memcpy
(
buf
+
16
,
msg_key
,
16
);
memcpy
(
buf
+
32
,
E
->
key
+
12
,
16
);
sha1
(
buf
,
48
,
sha1b_buffer
);
memcpy
(
buf
,
E
->
key
+
16
,
32
);
memcpy
(
buf
+
32
,
msg_key
,
16
);
sha1
(
buf
,
48
,
sha1c_buffer
);
memcpy
(
buf
,
msg_key
,
16
);
memcpy
(
buf
+
16
,
E
->
key
+
24
,
32
);
sha1
(
buf
,
48
,
sha1d_buffer
);
static
unsigned
char
key
[
32
];
memcpy
(
key
,
sha1a_buffer
+
0
,
8
);
memcpy
(
key
+
8
,
sha1b_buffer
+
8
,
12
);
memcpy
(
key
+
20
,
sha1c_buffer
+
4
,
12
);
static
unsigned
char
iv
[
32
];
memcpy
(
iv
,
sha1a_buffer
+
8
,
12
);
memcpy
(
iv
+
12
,
sha1b_buffer
+
0
,
8
);
memcpy
(
iv
+
20
,
sha1c_buffer
+
16
,
4
);
memcpy
(
iv
+
24
,
sha1d_buffer
+
0
,
8
);
AES_KEY
aes_key
;
AES_set_encrypt_key
(
key
,
256
,
&
aes_key
);
AES_ige_encrypt
((
void
*
)
encr_ptr
,
(
void
*
)
encr_ptr
,
4
*
(
encr_end
-
encr_ptr
),
&
aes_key
,
iv
,
1
);
return
(
void
*
)
msg_key
;
}
void
encr_start
(
void
)
{
encr_extra
=
packet_ptr
;
packet_ptr
+=
1
;
// str len
packet_ptr
+=
2
;
// fingerprint
packet_ptr
+=
4
;
// msg_key
packet_ptr
+=
1
;
// len
}
void
encr_finish
(
struct
secret_chat
*
E
)
{
int
l
=
packet_ptr
-
(
encr_extra
+
8
);
while
(((
packet_ptr
-
encr_extra
)
-
3
)
&
3
)
{
out_int
(
mrand48
());
}
*
encr_extra
=
((
packet_ptr
-
encr_extra
)
-
1
)
*
4
*
256
+
0xfe
;
encr_extra
++
;
*
(
long
long
*
)
encr_extra
=
E
->
key_fingerprint
;
encr_extra
+=
2
;
encr_extra
[
4
]
=
l
*
4
;
encr_ptr
=
encr_extra
+
4
;
encr_end
=
packet_ptr
;
memcpy
(
encr_extra
,
encrypt_decrypted_message
(
E
),
16
);
}
/* }}} */
/* {{{ Seng msg (plain text) */
int
msg_send_encr_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_messages_sent_encrypted_message
);
logprintf
(
"Sent
\n
"
);
struct
message
*
M
=
q
->
extra
;
M
->
date
=
fetch_int
();
message_insert
(
M
);
return
0
;
}
int
msg_send_on_answer
(
struct
query
*
q
UU
)
{
int
msg_send_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_sent_message
);
assert
(
fetch_int
()
==
(
int
)
CODE_messages_sent_message
);
int
id
=
fetch_int
();
// id
int
id
=
fetch_int
();
// id
int
date
=
fetch_int
();
// date
fetch_date
();
fetch_pts
();
fetch_pts
();
int
seq
=
fetch_int
();
// seq
fetch_seq
();
struct
message
*
M
=
q
->
extra
;
struct
message
*
M
=
q
->
extra
;
M
->
id
=
id
;
M
->
id
=
id
;
message_insert
(
M
);
message_insert
(
M
);
logprintf
(
"Sent: id = %d
, date = %d, seq = %d
\n
"
,
id
,
date
,
seq
);
logprintf
(
"Sent: id = %d
\n
"
,
id
);
return
0
;
return
0
;
}
}
...
@@ -631,10 +736,71 @@ struct query_methods msg_send_methods = {
...
@@ -631,10 +736,71 @@ struct query_methods msg_send_methods = {
.
on_answer
=
msg_send_on_answer
.
on_answer
=
msg_send_on_answer
};
};
struct
query_methods
msg_send_encr_methods
=
{
.
on_answer
=
msg_send_encr_on_answer
};
int
out_message_num
;
int
out_message_num
;
int
our_id
;
int
our_id
;
void
out_peer_id
(
peer_id_t
id
);
void
out_peer_id
(
peer_id_t
id
);
void
do_send_encr_message
(
peer_id_t
id
,
const
char
*
msg
,
int
len
)
{
peer_t
*
P
=
user_chat_get
(
id
);
if
(
!
P
)
{
logprintf
(
"Can not send to unknown encrypted chat
\n
"
);
return
;
}
if
(
P
->
encr_chat
.
state
!=
sc_ok
)
{
logprintf
(
"Chat is not yet initialized
\n
"
);
return
;
}
clear_packet
();
out_int
(
CODE_messages_send_encrypted
);
out_int
(
CODE_input_encrypted_chat
);
out_int
(
get_peer_id
(
id
));
out_long
(
P
->
encr_chat
.
access_hash
);
if
(
!
out_message_num
)
{
out_message_num
=
-
lrand48
();
}
out_long
((
--
out_message_num
)
-
(
4ll
<<
32
));
encr_start
();
//out_int (CODE_decrypted_message_layer);
//out_int (8);
out_int
(
CODE_decrypted_message
);
out_long
((
out_message_num
)
-
(
4ll
<<
32
));
static
int
buf
[
4
];
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
buf
[
i
]
=
mrand48
();
}
out_cstring
((
void
*
)
buf
,
16
);
out_cstring
((
void
*
)
msg
,
len
);
out_int
(
CODE_decrypted_message_media_empty
);
encr_finish
(
&
P
->
encr_chat
);
struct
message
*
M
=
malloc
(
sizeof
(
*
M
));
memset
(
M
,
0
,
sizeof
(
*
M
));
M
->
from_id
=
MK_USER
(
our_id
);
M
->
to_id
=
id
;
M
->
unread
=
1
;
M
->
message
=
malloc
(
len
+
1
);
memcpy
(
M
->
message
,
msg
,
len
);
M
->
message
[
len
]
=
0
;
M
->
message_len
=
len
;
M
->
out
=
1
;
M
->
media
.
type
=
CODE_message_media_empty
;
M
->
id
=
(
out_message_num
)
-
(
4ll
<<
32
);
M
->
date
=
time
(
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
);
print_message
(
M
);
}
void
do_send_message
(
peer_id_t
id
,
const
char
*
msg
,
int
len
)
{
void
do_send_message
(
peer_id_t
id
,
const
char
*
msg
,
int
len
)
{
if
(
get_peer_type
(
id
)
==
PEER_ENCR_CHAT
)
{
do_send_encr_message
(
id
,
msg
,
len
);
return
;
}
if
(
!
out_message_num
)
{
if
(
!
out_message_num
)
{
out_message_num
=
-
lrand48
();
out_message_num
=
-
lrand48
();
}
}
...
@@ -659,7 +825,9 @@ void do_send_message (peer_id_t id, const char *msg, int len) {
...
@@ -659,7 +825,9 @@ void do_send_message (peer_id_t id, const char *msg, int len) {
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
);
print_message
(
M
);
print_message
(
M
);
}
}
/* }}} */
/* {{{ Send text file */
void
do_send_text
(
peer_id_t
id
,
char
*
file_name
)
{
void
do_send_text
(
peer_id_t
id
,
char
*
file_name
)
{
int
fd
=
open
(
file_name
,
O_RDONLY
);
int
fd
=
open
(
file_name
,
O_RDONLY
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
...
@@ -681,19 +849,29 @@ void do_send_text (peer_id_t id, char *file_name) {
...
@@ -681,19 +849,29 @@ void do_send_text (peer_id_t id, char *file_name) {
close
(
fd
);
close
(
fd
);
}
}
}
}
/* }}} */
int
mark_read_on_receive
(
struct
query
*
q
UU
)
{
int
mark_read_on_receive
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_affected_history
);
assert
(
fetch_int
()
==
(
int
)
CODE_messages_affected_history
);
fetch_
int
();
// pts
fetch_
pts
();
fetch_
int
();
// seq
fetch_
seq
();
fetch_int
();
// offset
fetch_int
();
// offset
return
0
;
return
0
;
}
}
int
mark_read_encr_on_receive
(
struct
query
*
q
UU
)
{
fetch_bool
();
return
0
;
}
struct
query_methods
mark_read_methods
=
{
struct
query_methods
mark_read_methods
=
{
.
on_answer
=
mark_read_on_receive
.
on_answer
=
mark_read_on_receive
};
};
struct
query_methods
mark_read_encr_methods
=
{
.
on_answer
=
mark_read_encr_on_receive
};
void
do_messages_mark_read
(
peer_id_t
id
,
int
max_id
)
{
void
do_messages_mark_read
(
peer_id_t
id
,
int
max_id
)
{
clear_packet
();
clear_packet
();
out_int
(
CODE_messages_read_history
);
out_int
(
CODE_messages_read_history
);
...
@@ -703,6 +881,34 @@ void do_messages_mark_read (peer_id_t id, int max_id) {
...
@@ -703,6 +881,34 @@ void do_messages_mark_read (peer_id_t id, int max_id) {
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
);
}
}
void
do_messages_mark_read_encr
(
peer_id_t
id
,
long
long
access_hash
,
int
last_time
)
{
clear_packet
();
out_int
(
CODE_messages_read_encrypted_history
);
out_int
(
CODE_input_encrypted_chat
);
out_int
(
get_peer_id
(
id
));
out_long
(
access_hash
);
out_int
(
last_time
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_encr_methods
,
0
);
}
void
do_mark_read
(
peer_id_t
id
)
{
peer_t
*
P
=
user_chat_get
(
id
);
if
(
!
P
)
{
rprintf
(
"Unknown peer
\n
"
);
return
;
}
if
(
!
P
->
last
)
{
rprintf
(
"Unknown last peer message
\n
"
);
return
;
}
if
(
get_peer_type
(
id
)
==
PEER_USER
||
get_peer_type
(
id
)
==
PEER_CHAT
)
{
do_messages_mark_read
(
id
,
P
->
last
->
id
);
return
;
}
assert
(
get_peer_type
(
id
)
==
PEER_ENCR_CHAT
);
do_messages_mark_read_encr
(
id
,
P
->
encr_chat
.
access_hash
,
P
->
last
->
date
);
}
int
get_history_on_answer
(
struct
query
*
q
UU
)
{
int
get_history_on_answer
(
struct
query
*
q
UU
)
{
static
struct
message
*
ML
[
10000
];
static
struct
message
*
ML
[
10000
];
int
i
;
int
i
;
...
@@ -919,8 +1125,8 @@ int send_file_on_answer (struct query *q UU) {
...
@@ -919,8 +1125,8 @@ int send_file_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_user
();
fetch_alloc_user
();
}
}
fetch_
int
();
// pts
fetch_
pts
();
fetch_
int
();
// seq
fetch_
seq
();
print_message
(
M
);
print_message
(
M
);
return
0
;
return
0
;
}
}
...
@@ -1029,8 +1235,8 @@ int fwd_msg_on_answer (struct query *q UU) {
...
@@ -1029,8 +1235,8 @@ int fwd_msg_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_user
();
fetch_alloc_user
();
}
}
fetch_
int
();
// pts
fetch_
pts
();
fetch_
int
();
// seq
fetch_
seq
();
print_message
(
M
);
print_message
(
M
);
return
0
;
return
0
;
}
}
...
@@ -1041,7 +1247,7 @@ struct query_methods fwd_msg_methods = {
...
@@ -1041,7 +1247,7 @@ struct query_methods fwd_msg_methods = {
void
do_forward_message
(
peer_id_t
id
,
int
n
)
{
void
do_forward_message
(
peer_id_t
id
,
int
n
)
{
clear_packet
();
clear_packet
();
out_int
(
CODE_invoke_with_layer
3
);
out_int
(
CODE_invoke_with_layer
9
);
out_int
(
CODE_messages_forward_message
);
out_int
(
CODE_messages_forward_message
);
out_peer_id
(
id
);
out_peer_id
(
id
);
out_int
(
n
);
out_int
(
n
);
...
@@ -1063,8 +1269,8 @@ int rename_chat_on_answer (struct query *q UU) {
...
@@ -1063,8 +1269,8 @@ int rename_chat_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_user
();
fetch_alloc_user
();
}
}
fetch_
int
();
// pts
fetch_
pts
();
fetch_
int
();
// seq
fetch_
seq
();
print_message
(
M
);
print_message
(
M
);
return
0
;
return
0
;
}
}
...
@@ -1509,3 +1715,241 @@ void do_msg_search (peer_id_t id, int from, int to, int limit, const char *s) {
...
@@ -1509,3 +1715,241 @@ void do_msg_search (peer_id_t id, int from, int to, int limit, const char *s) {
out_int
(
limit
);
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
);
}
}
int
send_encr_accept_on_answer
(
struct
query
*
q
UU
)
{
struct
secret_chat
*
E
=
fetch_alloc_encrypted_chat
();
if
(
E
->
state
==
sc_ok
)
{
print_start
();
push_color
(
COLOR_YELLOW
);
printf
(
"Encrypted connection with "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" established
\n
"
);
pop_color
();
print_end
();
}
else
{
print_start
();
push_color
(
COLOR_YELLOW
);
printf
(
"Encrypted connection with "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" failed
\n
"
);
pop_color
();
print_end
();
}
return
0
;
}
struct
query_methods
send_encr_accept_methods
=
{
.
on_answer
=
send_encr_accept_on_answer
};
int
encr_root
;
unsigned
char
*
encr_prime
;
int
encr_param_version
;
BN_CTX
*
ctx
;
void
do_send_accept_encr_chat
(
struct
secret_chat
*
E
,
unsigned
char
*
random
)
{
int
i
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
*
(((
int
*
)
random
)
+
i
)
^=
mrand48
();
}
BIGNUM
*
b
=
BN_bin2bn
(
random
,
256
,
0
);
assert
(
b
);
BIGNUM
*
g_a
=
BN_bin2bn
(
E
->
g_key
,
256
,
0
);
assert
(
g_a
);
if
(
!
ctx
)
{
ctx
=
BN_CTX_new
();
BN_CTX_init
(
ctx
);
}
BIGNUM
*
p
=
BN_bin2bn
(
encr_prime
,
256
,
0
);
BIGNUM
*
r
=
BN_new
();
BN_init
(
r
);
BN_mod_exp
(
r
,
g_a
,
b
,
p
,
ctx
);
memset
(
E
->
key
,
0
,
sizeof
(
E
->
key
));
BN_bn2bin
(
r
,
(
void
*
)
E
->
key
);
for
(
i
=
0
;
i
<
64
;
i
++
)
{
E
->
key
[
i
]
^=
*
(((
int
*
)
E
->
nonce
)
+
i
);
}
static
unsigned
char
sha_buffer
[
20
];
sha1
((
void
*
)
E
->
key
,
256
,
sha_buffer
);
E
->
key_fingerprint
=
*
(
long
long
*
)(
sha_buffer
+
12
);
clear_packet
();
out_int
(
CODE_messages_accept_encryption
);
out_int
(
CODE_input_encrypted_chat
);
logprintf
(
"id = %d
\n
"
,
get_peer_id
(
E
->
id
));
out_int
(
get_peer_id
(
E
->
id
));
out_long
(
E
->
access_hash
);
BN_set_word
(
g_a
,
encr_root
);
BN_mod_exp
(
r
,
g_a
,
b
,
p
,
ctx
);
static
unsigned
char
buf
[
256
];
memset
(
buf
,
0
,
sizeof
(
buf
));
BN_bn2bin
(
r
,
buf
);
out_cstring
((
void
*
)
buf
,
256
);
out_long
(
E
->
key_fingerprint
);
BN_clear_free
(
b
);
BN_clear_free
(
g_a
);
BN_clear_free
(
p
);
BN_clear_free
(
r
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
);
}
int
get_dh_config_on_answer
(
struct
query
*
q
UU
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_messages_dh_config
||
x
==
CODE_messages_dh_config_not_modified
);
if
(
x
==
CODE_messages_dh_config
)
{
encr_root
=
fetch_int
();
if
(
encr_prime
)
{
free
(
encr_prime
);
}
int
l
=
prefetch_strlen
();
assert
(
l
==
256
);
encr_prime
=
(
void
*
)
fetch_str_dup
();
encr_param_version
=
fetch_int
();
}
int
l
=
prefetch_strlen
();
assert
(
l
==
256
);
unsigned
char
*
random
=
(
void
*
)
fetch_str_dup
();
if
(
q
->
extra
)
{
do_send_accept_encr_chat
(
q
->
extra
,
random
);
free
(
random
);
}
else
{
free
(
random
);
}
return
0
;
}
struct
query_methods
get_dh_config_methods
=
{
.
on_answer
=
get_dh_config_on_answer
};
void
do_accept_encr_chat_request
(
struct
secret_chat
*
E
)
{
assert
(
E
->
state
==
sc_request
);
clear_packet
();
out_int
(
CODE_messages_get_dh_config
);
out_int
(
encr_param_version
);
out_int
(
256
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
E
);
}
int
unread_messages
;
int
difference_got
;
int
seq
,
pts
,
qts
,
last_date
;
int
get_state_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_state
);
pts
=
fetch_int
();
qts
=
fetch_int
();
last_date
=
fetch_int
();
seq
=
fetch_int
();
unread_messages
=
fetch_int
();
write_state_file
();
difference_got
=
1
;
return
0
;
}
int
get_difference_on_answer
(
struct
query
*
q
UU
)
{
unsigned
x
=
fetch_int
();
if
(
x
==
CODE_updates_difference_empty
)
{
fetch_date
();
fetch_seq
();
difference_got
=
1
;
}
else
if
(
x
==
CODE_updates_difference
||
x
==
CODE_updates_difference_slice
)
{
int
n
,
i
;
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
static
struct
message
*
ML
[
10000
];
int
ml_pos
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
if
(
ml_pos
<
10000
)
{
ML
[
ml_pos
++
]
=
fetch_alloc_message
();
}
else
{
fetch_alloc_message
();
}
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
if
(
ml_pos
<
10000
)
{
ML
[
ml_pos
++
]
=
fetch_alloc_encrypted_message
();
}
else
{
fetch_alloc_encrypted_message
();
}
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
work_update
(
0
,
0
);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_chat
();
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_alloc_user
();
}
assert
(
fetch_int
()
==
(
int
)
CODE_updates_state
);
pts
=
fetch_int
();
qts
=
fetch_int
();
last_date
=
fetch_int
();
seq
=
fetch_int
();
unread_messages
=
fetch_int
();
write_state_file
();
for
(
i
=
0
;
i
<
ml_pos
;
i
++
)
{
print_message
(
ML
[
i
]);
}
if
(
x
==
CODE_updates_difference_slice
)
{
do_get_difference
();
}
else
{
difference_got
=
1
;
}
}
else
{
assert
(
0
);
}
return
0
;
}
struct
query_methods
get_state_methods
=
{
.
on_answer
=
get_state_on_answer
};
struct
query_methods
get_difference_methods
=
{
.
on_answer
=
get_difference_on_answer
};
void
do_get_difference
(
void
)
{
difference_got
=
0
;
clear_packet
();
out_int
(
CODE_invoke_with_layer9
);
out_int
(
CODE_init_connection
);
out_int
(
TG_APP_ID
);
if
(
allow_send_linux_version
)
{
struct
utsname
st
;
uname
(
&
st
);
out_string
(
st
.
machine
);
static
char
buf
[
1000000
];
sprintf
(
buf
,
"%s %s %s"
,
st
.
sysname
,
st
.
release
,
st
.
version
);
out_string
(
buf
);
out_string
(
TG_VERSION
" (build "
TG_BUILD
")"
);
out_string
(
"En"
);
}
else
{
out_string
(
"x86"
);
out_string
(
"Linux"
);
out_string
(
TG_VERSION
);
out_string
(
"en"
);
}
if
(
seq
>
0
)
{
out_int
(
CODE_updates_get_difference
);
out_int
(
pts
);
out_int
(
last_date
);
out_int
(
qts
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_difference_methods
,
0
);
}
else
{
out_int
(
CODE_updates_get_state
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_state_methods
,
0
);
}
}
queries.h
View file @
923845d6
...
@@ -94,5 +94,8 @@ void do_import_auth (int num);
...
@@ -94,5 +94,8 @@ void do_import_auth (int num);
void
do_export_auth
(
int
num
);
void
do_export_auth
(
int
num
);
void
do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
);
void
do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
);
void
do_msg_search
(
peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
);
void
do_msg_search
(
peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
);
void
do_accept_encr_chat_request
(
struct
secret_chat
*
E
);
void
do_get_difference
(
void
);
void
do_mark_read
(
peer_id_t
id
);
#endif
#endif
structures.c
View file @
923845d6
...
@@ -32,6 +32,10 @@
...
@@ -32,6 +32,10 @@
int
verbosity
;
int
verbosity
;
peer_t
*
Peers
[
MAX_USER_NUM
];
peer_t
*
Peers
[
MAX_USER_NUM
];
int
peer_num
;
int
encr_chats_allocated
;
int
geo_chats_allocated
;
void
fetch_file_location
(
struct
file_location
*
loc
)
{
void
fetch_file_location
(
struct
file_location
*
loc
)
{
int
x
=
fetch_int
();
int
x
=
fetch_int
();
if
(
x
==
CODE_file_location_unavailable
)
{
if
(
x
==
CODE_file_location_unavailable
)
{
...
@@ -68,55 +72,31 @@ void fetch_user_status (struct user_status *S) {
...
@@ -68,55 +72,31 @@ void fetch_user_status (struct user_status *S) {
}
}
int
our_id
;
int
our_id
;
int
user_num
;
int
chat_num
;
void
fetch_user
(
struct
user
*
U
)
{
char
*
create_print_name
(
peer_id_t
id
,
const
char
*
a1
,
const
char
*
a2
,
const
char
*
a3
,
const
char
*
a4
)
{
unsigned
x
=
fetch_int
();
const
char
*
d
[
4
];
assert
(
x
==
CODE_user_empty
||
x
==
CODE_user_self
||
x
==
CODE_user_contact
||
x
==
CODE_user_request
||
x
==
CODE_user_foreign
||
x
==
CODE_user_deleted
);
d
[
0
]
=
a1
;
d
[
1
]
=
a2
;
d
[
2
]
=
a3
;
d
[
3
]
=
a4
;
U
->
id
=
MK_USER
(
fetch_int
());
static
char
buf
[
10000
];
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
|
FLAG_USER_SELF
|
FLAG_USER_FOREIGN
|
FLAG_USER_CONTACT
);
int
i
;
if
(
x
==
CODE_user_empty
)
{
int
p
=
0
;
U
->
flags
|=
FLAG_EMPTY
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
return
;
if
(
d
[
i
]
&&
strlen
(
d
[
i
]))
{
}
p
+=
snprintf
(
buf
+
p
,
9999
-
p
,
"%s%s"
,
p
?
"_"
:
""
,
d
[
i
]);
if
(
x
==
CODE_user_self
)
{
assert
(
p
<
9990
);
assert
(
!
our_id
||
(
our_id
==
get_peer_id
(
U
->
id
)));
if
(
!
our_id
)
{
our_id
=
get_peer_id
(
U
->
id
);
write_auth_file
();
}
}
if
(
U
->
first_name
)
{
free
(
U
->
first_name
);
}
if
(
U
->
last_name
)
{
free
(
U
->
last_name
);
}
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
U
->
first_name
=
fetch_str_dup
();
U
->
last_name
=
fetch_str_dup
();
if
(
!
strlen
(
U
->
first_name
))
{
if
(
!
strlen
(
U
->
last_name
))
{
U
->
print_name
=
strdup
(
"none"
);
}
else
{
U
->
print_name
=
strdup
(
U
->
last_name
);
}
}
else
{
if
(
!
strlen
(
U
->
last_name
))
{
U
->
print_name
=
strdup
(
U
->
first_name
);
}
else
{
U
->
print_name
=
malloc
(
strlen
(
U
->
first_name
)
+
strlen
(
U
->
last_name
)
+
2
);
sprintf
(
U
->
print_name
,
"%s_%s"
,
U
->
first_name
,
U
->
last_name
);
}
}
}
}
char
*
s
=
U
->
print_name
;
char
*
s
=
buf
;
while
(
*
s
)
{
while
(
*
s
)
{
if
(
*
s
==
' '
)
{
*
s
=
'_'
;
}
if
(
*
s
==
' '
)
{
*
s
=
'_'
;
}
s
++
;
s
++
;
}
}
s
=
buf
;
int
cc
=
0
;
int
cc
=
0
;
while
(
1
)
{
while
(
1
)
{
int
ok
=
1
;
int
ok
=
1
;
int
i
;
int
i
;
for
(
i
=
0
;
i
<
user_num
+
chat
_num
;
i
++
)
{
for
(
i
=
0
;
i
<
peer
_num
;
i
++
)
{
if
(
Peers
[
i
]
!=
(
void
*
)
U
&&
Peers
[
i
]
->
print_name
&&
!
strcmp
(
Peers
[
i
]
->
print_name
,
U
->
print_name
))
{
if
(
cmp_peer_id
(
Peers
[
i
]
->
id
,
id
)
&&
Peers
[
i
]
->
print_name
&&
!
strcmp
(
Peers
[
i
]
->
print_name
,
s
))
{
ok
=
0
;
ok
=
0
;
break
;
break
;
}
}
...
@@ -127,32 +107,52 @@ void fetch_user (struct user *U) {
...
@@ -127,32 +107,52 @@ void fetch_user (struct user *U) {
cc
++
;
cc
++
;
assert
(
cc
<=
99
);
assert
(
cc
<=
99
);
if
(
cc
==
1
)
{
if
(
cc
==
1
)
{
int
l
=
strlen
(
U
->
print_name
);
int
l
=
strlen
(
s
);
char
*
s
=
malloc
(
l
+
3
);
memcpy
(
s
,
U
->
print_name
,
l
);
s
[
l
+
2
]
=
0
;
s
[
l
+
2
]
=
0
;
s
[
l
]
=
'#'
;
s
[
l
]
=
'#'
;
s
[
l
+
1
]
=
'1'
;
s
[
l
+
1
]
=
'1'
;
free
(
U
->
print_name
);
U
->
print_name
=
s
;
}
else
if
(
cc
==
10
)
{
}
else
if
(
cc
==
10
)
{
int
l
=
strlen
(
U
->
print_name
);
int
l
=
strlen
(
s
);
char
*
s
=
malloc
(
l
+
2
);
memcpy
(
s
,
U
->
print_name
,
l
);
s
[
l
+
1
]
=
0
;
s
[
l
+
1
]
=
0
;
s
[
l
]
=
'0'
;
s
[
l
]
=
'0'
;
s
[
l
-
1
]
=
'1'
;
s
[
l
-
1
]
=
'1'
;
free
(
U
->
print_name
);
U
->
print_name
=
s
;
}
else
{
}
else
{
int
l
=
strlen
(
U
->
print_name
);
int
l
=
strlen
(
s
);
U
->
print_name
[
l
-
1
]
++
;
s
[
l
-
1
]
++
;
if
(
U
->
print_name
[
l
-
1
]
>
'9'
)
{
int
cc
=
l
-
1
;
U
->
print_name
[
l
-
1
]
=
'0'
;
while
(
s
[
cc
]
>
'9'
)
{
U
->
print_name
[
l
-
2
]
++
;
s
[
cc
]
=
'0'
;
s
[
cc
-
1
]
++
;
cc
--
;
}
}
}
}
}
}
return
strdup
(
s
);
}
void
fetch_user
(
struct
user
*
U
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_user_empty
||
x
==
CODE_user_self
||
x
==
CODE_user_contact
||
x
==
CODE_user_request
||
x
==
CODE_user_foreign
||
x
==
CODE_user_deleted
);
U
->
id
=
MK_USER
(
fetch_int
());
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
|
FLAG_USER_SELF
|
FLAG_USER_FOREIGN
|
FLAG_USER_CONTACT
);
if
(
x
==
CODE_user_empty
)
{
U
->
flags
|=
FLAG_EMPTY
;
return
;
}
if
(
x
==
CODE_user_self
)
{
assert
(
!
our_id
||
(
our_id
==
get_peer_id
(
U
->
id
)));
if
(
!
our_id
)
{
our_id
=
get_peer_id
(
U
->
id
);
write_auth_file
();
}
}
if
(
U
->
first_name
)
{
free
(
U
->
first_name
);
}
if
(
U
->
last_name
)
{
free
(
U
->
last_name
);
}
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
U
->
first_name
=
fetch_str_dup
();
U
->
last_name
=
fetch_str_dup
();
U
->
print_name
=
create_print_name
(
U
->
id
,
U
->
first_name
,
U
->
last_name
,
0
,
0
);
if
(
x
==
CODE_user_deleted
)
{
if
(
x
==
CODE_user_deleted
)
{
U
->
flags
|=
FLAG_DELETED
;
U
->
flags
|=
FLAG_DELETED
;
return
;
return
;
...
@@ -197,47 +197,96 @@ void fetch_encrypted_chat (struct secret_chat *U) {
...
@@ -197,47 +197,96 @@ void fetch_encrypted_chat (struct secret_chat *U) {
assert
(
x
==
CODE_encrypted_chat_empty
||
x
==
CODE_encrypted_chat_waiting
||
x
==
CODE_encrypted_chat_requested
||
x
==
CODE_encrypted_chat
||
x
==
CODE_encrypted_chat_discarded
);
assert
(
x
==
CODE_encrypted_chat_empty
||
x
==
CODE_encrypted_chat_waiting
||
x
==
CODE_encrypted_chat_requested
||
x
==
CODE_encrypted_chat
||
x
==
CODE_encrypted_chat_discarded
);
U
->
id
=
MK_ENCR_CHAT
(
fetch_int
());
U
->
id
=
MK_ENCR_CHAT
(
fetch_int
());
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
);
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
);
enum
secret_chat_state
old_state
=
U
->
state
;
if
(
x
==
CODE_encrypted_chat_empty
)
{
if
(
x
==
CODE_encrypted_chat_empty
)
{
U
->
state
=
sc_none
;
U
->
state
=
sc_none
;
U
->
flags
|=
FLAG_EMPTY
;
U
->
flags
|=
FLAG_EMPTY
;
if
(
U
->
state
!=
old_state
)
{
write_secret_chat_file
();
}
return
;
return
;
}
}
if
(
x
==
CODE_encrypted_chat_discarded
)
{
if
(
x
==
CODE_encrypted_chat_discarded
)
{
U
->
state
=
sc_deleted
;
U
->
state
=
sc_deleted
;
U
->
flags
|=
FLAG_DELETED
;
U
->
flags
|=
FLAG_DELETED
;
if
(
U
->
state
!=
old_state
)
{
write_secret_chat_file
();
}
return
;
return
;
}
}
U
->
access_hash
=
fetch_long
();
U
->
access_hash
=
fetch_long
();
U
->
date
=
fetch_int
();
U
->
date
=
fetch_int
();
U
->
admin_id
=
fetch_int
();
U
->
admin_id
=
fetch_int
();
U
->
user_id
=
fetch_int
()
+
U
->
admin_id
-
our_id
;
U
->
user_id
=
fetch_int
()
+
U
->
admin_id
-
our_id
;
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
peer_t
*
P
=
user_chat_get
(
MK_USER
(
U
->
user_id
));
if
(
P
)
{
U
->
print_name
=
create_print_name
(
U
->
id
,
"!"
,
P
->
user
.
first_name
,
P
->
user
.
last_name
,
0
);
}
else
{
static
char
buf
[
100
];
sprintf
(
buf
,
"user#%d"
,
U
->
user_id
);
U
->
print_name
=
create_print_name
(
U
->
id
,
"!"
,
buf
,
0
,
0
);
}
if
(
x
==
CODE_encrypted_chat_waiting
)
{
if
(
x
==
CODE_encrypted_chat_waiting
)
{
U
->
state
=
sc_waiting
;
U
->
state
=
sc_waiting
;
}
else
if
(
x
==
CODE_encrypted_chat_requested
)
{
}
else
if
(
x
==
CODE_encrypted_chat_requested
)
{
U
->
state
=
sc_request
;
U
->
state
=
sc_request
;
if
(
!
U
->
g_key
)
{
if
(
!
U
->
g_key
)
{
U
->
g_key
=
malloc
(
256
);
U
->
g_key
=
malloc
(
256
);
}
}
memset
(
U
->
g_key
,
0
,
256
);
if
(
!
U
->
nonce
)
{
if
(
!
U
->
nonce
)
{
U
->
nonce
=
malloc
(
256
);
U
->
nonce
=
malloc
(
256
);
}
}
assert
(
prefetch_strlen
()
==
256
);
memset
(
U
->
nonce
,
0
,
256
);
memcpy
(
U
->
g_key
,
fetch_str
(
256
),
256
);
int
l
=
prefetch_strlen
();
assert
(
prefetch_strlen
()
==
256
);
char
*
s
=
fetch_str
(
l
);
memcpy
(
U
->
nonce
,
fetch_str
(
256
),
256
);
if
(
l
<
256
)
{
memcpy
(
U
->
g_key
+
256
-
l
,
s
,
l
);
}
else
{
memcpy
(
U
->
g_key
,
s
+
(
l
-
256
),
256
);
}
l
=
prefetch_strlen
();
s
=
fetch_str
(
l
);
if
(
l
<
256
)
{
memcpy
(
U
->
nonce
+
256
-
l
,
s
,
l
);
}
else
{
memcpy
(
U
->
nonce
,
s
+
(
l
-
256
),
256
);
}
}
else
{
}
else
{
U
->
state
=
sc_ok
;
U
->
state
=
sc_ok
;
if
(
!
U
->
g_key
)
{
if
(
!
U
->
g_key
)
{
U
->
g_key
=
malloc
(
256
);
U
->
g_key
=
malloc
(
256
);
}
}
memset
(
U
->
g_key
,
0
,
256
);
if
(
!
U
->
nonce
)
{
if
(
!
U
->
nonce
)
{
U
->
nonce
=
malloc
(
256
);
U
->
nonce
=
malloc
(
256
);
}
}
assert
(
prefetch_strlen
()
==
256
);
memset
(
U
->
nonce
,
0
,
256
);
memcpy
(
U
->
g_key
,
fetch_str
(
256
),
256
);
int
l
=
prefetch_strlen
();
assert
(
prefetch_strlen
()
==
256
);
char
*
s
=
fetch_str
(
l
);
memcpy
(
U
->
nonce
,
fetch_str
(
256
),
256
);
if
(
l
<
256
)
{
U
->
key_fingerprint
=
fetch_long
();
memcpy
(
U
->
g_key
+
256
-
l
,
s
,
l
);
}
else
{
memcpy
(
U
->
g_key
,
s
+
(
l
-
256
),
256
);
}
l
=
prefetch_strlen
();
s
=
fetch_str
(
l
);
if
(
l
<
256
)
{
memcpy
(
U
->
nonce
+
256
-
l
,
s
,
l
);
}
else
{
memcpy
(
U
->
nonce
,
s
+
(
l
-
256
),
256
);
}
if
(
!
U
->
key_fingerprint
)
{
U
->
key_fingerprint
=
fetch_long
();
}
else
{
assert
(
U
->
key_fingerprint
==
fetch_long
());
}
}
if
(
U
->
state
!=
old_state
)
{
write_secret_chat_file
();
}
}
}
}
...
@@ -294,12 +343,7 @@ void fetch_chat (struct chat *C) {
...
@@ -294,12 +343,7 @@ void fetch_chat (struct chat *C) {
if
(
C
->
title
)
{
free
(
C
->
title
);
}
if
(
C
->
title
)
{
free
(
C
->
title
);
}
if
(
C
->
print_title
)
{
free
(
C
->
print_title
);
}
if
(
C
->
print_title
)
{
free
(
C
->
print_title
);
}
C
->
title
=
fetch_str_dup
();
C
->
title
=
fetch_str_dup
();
C
->
print_title
=
strdup
(
C
->
title
);
C
->
print_title
=
create_print_name
(
C
->
id
,
C
->
title
,
0
,
0
,
0
);
char
*
s
=
C
->
print_title
;
while
(
*
s
)
{
if
(
*
s
==
' '
)
{
*
s
=
'_'
;
}
s
++
;
}
if
(
x
==
CODE_chat
)
{
if
(
x
==
CODE_chat
)
{
unsigned
y
=
fetch_int
();
unsigned
y
=
fetch_int
();
if
(
y
==
CODE_chat_photo_empty
)
{
if
(
y
==
CODE_chat_photo_empty
)
{
...
@@ -499,9 +543,9 @@ void fetch_message_short (struct message *M) {
...
@@ -499,9 +543,9 @@ void fetch_message_short (struct message *M) {
M
->
to_id
=
MK_USER
(
our_id
);
M
->
to_id
=
MK_USER
(
our_id
);
M
->
from_id
=
MK_USER
(
fetch_int
());
M
->
from_id
=
MK_USER
(
fetch_int
());
M
->
message
=
fetch_str_dup
();
M
->
message
=
fetch_str_dup
();
fetch_
int
();
// pts
fetch_
pts
();
M
->
date
=
fetch_int
();
M
->
date
=
fetch_int
();
fetch_
int
();
// seq
fetch_
seq
();
M
->
media
.
type
=
CODE_message_media_empty
;
M
->
media
.
type
=
CODE_message_media_empty
;
M
->
unread
=
1
;
M
->
unread
=
1
;
}
}
...
@@ -512,9 +556,9 @@ void fetch_message_short_chat (struct message *M) {
...
@@ -512,9 +556,9 @@ void fetch_message_short_chat (struct message *M) {
M
->
from_id
=
MK_USER
(
fetch_int
());
M
->
from_id
=
MK_USER
(
fetch_int
());
M
->
to_id
=
MK_CHAT
(
fetch_int
());
M
->
to_id
=
MK_CHAT
(
fetch_int
());
M
->
message
=
fetch_str_dup
();
M
->
message
=
fetch_str_dup
();
fetch_
int
();
// pts
fetch_
pts
();
M
->
date
=
fetch_int
();
M
->
date
=
fetch_int
();
fetch_
int
();
// seq
fetch_
seq
();
M
->
media
.
type
=
CODE_message_media_empty
;
M
->
media
.
type
=
CODE_message_media_empty
;
M
->
unread
=
1
;
M
->
unread
=
1
;
}
}
...
@@ -554,7 +598,7 @@ void fetch_message_media_encrypted (struct message_media *M) {
...
@@ -554,7 +598,7 @@ void fetch_message_media_encrypted (struct message_media *M) {
memset
(
M
,
0
,
sizeof
(
*
M
));
memset
(
M
,
0
,
sizeof
(
*
M
));
unsigned
x
=
fetch_int
();
unsigned
x
=
fetch_int
();
int
l
;
int
l
;
switch
(
M
->
type
)
{
switch
(
x
)
{
case
CODE_decrypted_message_media_empty
:
case
CODE_decrypted_message_media_empty
:
M
->
type
=
CODE_message_media_empty
;
M
->
type
=
CODE_message_media_empty
;
break
;
break
;
...
@@ -567,15 +611,25 @@ void fetch_message_media_encrypted (struct message_media *M) {
...
@@ -567,15 +611,25 @@ void fetch_message_media_encrypted (struct message_media *M) {
M
->
encr_photo
.
w
=
fetch_int
();
M
->
encr_photo
.
w
=
fetch_int
();
M
->
encr_photo
.
h
=
fetch_int
();
M
->
encr_photo
.
h
=
fetch_int
();
M
->
encr_photo
.
size
=
fetch_int
();
M
->
encr_photo
.
size
=
fetch_int
();
l
=
fetch_int
();
assert
(
l
>
0
);
M
->
encr_photo
.
key
=
malloc
(
l
);
memcpy
(
M
->
encr_photo
.
key
,
fetch_str
(
l
),
l
);
l
=
fetch_int
();
l
=
prefetch_strlen
();
assert
(
l
>
0
);
assert
(
l
>
0
);
M
->
encr_photo
.
iv
=
malloc
(
l
);
M
->
encr_photo
.
key
=
malloc
(
32
);
memcpy
(
M
->
encr_photo
.
iv
,
fetch_str
(
l
),
l
);
memset
(
M
->
encr_photo
.
key
,
0
,
32
);
if
(
l
<=
32
)
{
memcpy
(
M
->
encr_photo
.
key
+
(
32
-
l
),
fetch_str
(
l
),
l
);
}
else
{
memcpy
(
M
->
encr_photo
.
key
,
fetch_str
(
l
)
+
(
l
-
32
),
32
);
}
M
->
encr_photo
.
iv
=
malloc
(
32
);
l
=
prefetch_strlen
();
assert
(
l
>
0
);
memset
(
M
->
encr_photo
.
iv
,
0
,
32
);
if
(
l
<=
32
)
{
memcpy
(
M
->
encr_photo
.
iv
+
(
32
-
l
),
fetch_str
(
l
),
l
);
}
else
{
memcpy
(
M
->
encr_photo
.
iv
,
fetch_str
(
l
)
+
(
l
-
32
),
32
);
}
break
;
break
;
case
CODE_decrypted_message_media_video
:
case
CODE_decrypted_message_media_video
:
M
->
type
=
x
;
M
->
type
=
x
;
...
@@ -587,15 +641,25 @@ void fetch_message_media_encrypted (struct message_media *M) {
...
@@ -587,15 +641,25 @@ void fetch_message_media_encrypted (struct message_media *M) {
M
->
encr_video
.
h
=
fetch_int
();
M
->
encr_video
.
h
=
fetch_int
();
M
->
encr_video
.
size
=
fetch_int
();
M
->
encr_video
.
size
=
fetch_int
();
M
->
encr_video
.
duration
=
fetch_int
();
M
->
encr_video
.
duration
=
fetch_int
();
l
=
fetch_int
();
assert
(
l
>
0
);
M
->
encr_video
.
key
=
malloc
(
l
);
memcpy
(
M
->
encr_video
.
key
,
fetch_str
(
l
),
l
);
l
=
fetch_int
();
l
=
prefetch_strlen
();
assert
(
l
>
0
);
assert
(
l
>
0
);
M
->
encr_video
.
iv
=
malloc
(
l
);
M
->
encr_video
.
key
=
malloc
(
32
);
memcpy
(
M
->
encr_video
.
iv
,
fetch_str
(
l
),
l
);
memset
(
M
->
encr_photo
.
key
,
0
,
32
);
if
(
l
<=
32
)
{
memcpy
(
M
->
encr_video
.
key
+
(
32
-
l
),
fetch_str
(
l
),
l
);
}
else
{
memcpy
(
M
->
encr_video
.
key
,
fetch_str
(
l
)
+
(
l
-
32
),
32
);
}
M
->
encr_video
.
iv
=
malloc
(
32
);
l
=
prefetch_strlen
();
assert
(
l
>
0
);
memset
(
M
->
encr_video
.
iv
,
0
,
32
);
if
(
l
<=
32
)
{
memcpy
(
M
->
encr_video
.
iv
+
(
32
-
l
),
fetch_str
(
l
),
l
);
}
else
{
memcpy
(
M
->
encr_video
.
iv
,
fetch_str
(
l
)
+
(
l
-
32
),
32
);
}
break
;
break
;
/* case CODE_decrypted_message_media_file:
/* case CODE_decrypted_message_media_file:
M->type = x;
M->type = x;
...
@@ -719,24 +783,26 @@ int decrypt_encrypted_message (struct secret_chat *E) {
...
@@ -719,24 +783,26 @@ int decrypt_encrypted_message (struct secret_chat *E) {
memcpy
(
buf
+
16
,
E
->
key
+
24
,
32
);
memcpy
(
buf
+
16
,
E
->
key
+
24
,
32
);
sha1
(
buf
,
48
,
sha1d_buffer
);
sha1
(
buf
,
48
,
sha1d_buffer
);
static
unsigned
char
iv
[
32
];
memcpy
(
iv
,
sha1a_buffer
+
0
,
8
);
memcpy
(
iv
+
8
,
sha1b_buffer
+
8
,
12
);
memcpy
(
iv
+
20
,
sha1c_buffer
+
4
,
12
);
static
unsigned
char
key
[
32
];
static
unsigned
char
key
[
32
];
memcpy
(
key
,
sha1a_buffer
+
8
,
12
);
memcpy
(
key
,
sha1a_buffer
+
0
,
8
);
memcpy
(
key
+
12
,
sha1b_buffer
+
0
,
8
);
memcpy
(
key
+
8
,
sha1b_buffer
+
8
,
12
);
memcpy
(
key
+
20
,
sha1c_buffer
+
16
,
4
);
memcpy
(
key
+
20
,
sha1c_buffer
+
4
,
12
);
memcpy
(
key
+
24
,
sha1d_buffer
+
0
,
8
);
static
unsigned
char
iv
[
32
];
memcpy
(
iv
,
sha1a_buffer
+
8
,
12
);
memcpy
(
iv
+
12
,
sha1b_buffer
+
0
,
8
);
memcpy
(
iv
+
20
,
sha1c_buffer
+
16
,
4
);
memcpy
(
iv
+
24
,
sha1d_buffer
+
0
,
8
);
AES_KEY
aes_key
;
AES_KEY
aes_key
;
AES_set_decrypt_key
(
key
,
256
,
&
aes_key
);
AES_set_decrypt_key
(
key
,
256
,
&
aes_key
);
AES_ige_encrypt
((
void
*
)
decr_ptr
,
(
void
*
)
decr_ptr
,
4
*
(
decr_end
-
decr_ptr
),
&
aes_key
,
iv
,
0
);
AES_ige_encrypt
((
void
*
)
decr_ptr
,
(
void
*
)
decr_ptr
,
4
*
(
decr_end
-
decr_ptr
),
&
aes_key
,
iv
,
0
);
sha1
((
void
*
)
decr_ptr
,
4
*
(
decr_end
-
decr_ptr
),
sha1a_buffer
);
int
x
=
*
(
decr_ptr
);
assert
(
x
>=
0
&&
!
(
x
&
3
));
sha1
((
void
*
)
decr_ptr
,
4
+
x
,
sha1a_buffer
);
if
(
memcmp
(
sha1a_buffer
,
msg_key
,
16
))
{
if
(
memcmp
(
sha1a_buffer
+
4
,
msg_key
,
16
))
{
logprintf
(
"Sha1 mismatch
\n
"
);
logprintf
(
"Sha1 mismatch
\n
"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -747,40 +813,72 @@ void fetch_encrypted_message (struct message *M) {
...
@@ -747,40 +813,72 @@ void fetch_encrypted_message (struct message *M) {
memset
(
M
,
0
,
sizeof
(
*
M
));
memset
(
M
,
0
,
sizeof
(
*
M
));
unsigned
x
=
fetch_int
();
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_encrypted_message
||
x
==
CODE_encrypted_message_service
);
assert
(
x
==
CODE_encrypted_message
||
x
==
CODE_encrypted_message_service
);
peer_id_t
chat
=
MK_ENCR_CHAT
(
fetch_int
())
;
unsigned
sx
=
x
;
M
->
id
=
fetch_long
();
M
->
id
=
fetch_long
();
peer_id_t
chat
=
MK_ENCR_CHAT
(
fetch_int
());
M
->
to_id
=
chat
;
peer_t
*
P
=
user_chat_get
(
chat
);
peer_t
*
P
=
user_chat_get
(
chat
);
if
(
!
P
)
{
if
(
!
P
)
{
logprintf
(
"Encrypted message to unknown chat. Dropping
\n
"
);
logprintf
(
"Encrypted message to unknown chat. Dropping
\n
"
);
M
->
flags
|=
FLAG_EMPTY
;
}
}
M
->
date
=
fetch_int
();
M
->
date
=
fetch_int
();
int
len
=
prefetch_strlen
();
int
len
=
prefetch_strlen
();
assert
(
!
(
len
&
15
)
);
assert
(
(
len
&
15
)
==
8
);
decr_ptr
=
(
void
*
)
fetch_str
(
len
);
decr_ptr
=
(
void
*
)
fetch_str
(
len
);
decr_end
=
in_ptr
;
decr_end
=
decr_ptr
+
(
len
/
4
)
;
M
->
flags
|=
FLAG_ENCRYPTED
;
M
->
flags
|=
FLAG_ENCRYPTED
;
int
ok
=
0
;
if
(
P
)
{
if
(
*
(
long
long
*
)
decr_ptr
!=
P
->
encr_chat
.
key_fingerprint
)
{
logprintf
(
"Encrypted message with bad fingerprint to chat %s
\n
"
,
P
->
print_name
);
P
=
0
;
}
decr_ptr
+=
2
;
}
if
(
P
&&
decrypt_encrypted_message
(
&
P
->
encr_chat
)
>=
0
)
{
if
(
P
&&
decrypt_encrypted_message
(
&
P
->
encr_chat
)
>=
0
)
{
ok
=
1
;
int
*
save_in_ptr
=
in_ptr
;
int
*
save_in_end
=
in_end
;
in_ptr
=
decr_ptr
;
in_ptr
=
decr_ptr
;
int
l
=
fetch_int
();
in_end
=
in_ptr
+
l
;
unsigned
x
=
fetch_int
();
unsigned
x
=
fetch_int
();
if
(
x
==
CODE_decrypted_message_layer
)
{
if
(
x
==
CODE_decrypted_message_layer
)
{
int
layer
=
fetch_int
();
int
layer
=
fetch_int
();
assert
(
layer
>=
0
);
assert
(
layer
>=
0
);
x
=
fetch_int
();
x
=
fetch_int
();
}
}
assert
(
x
==
CODE_decrypted_message
);
assert
(
x
==
CODE_decrypted_message
||
x
==
CODE_decrypted_message_service
);
assert
(
M
->
id
=
fetch_long
());
assert
(
M
->
id
=
fetch_long
());
int
l
=
prefetch_strlen
();
l
=
prefetch_strlen
();
fetch_str
(
l
);
// random_bytes
fetch_str
(
l
);
// random_bytes
M
->
from_id
=
MK_USER
(
fetch_int
());
M
->
date
=
fetch_int
();
if
(
x
==
CODE_decrypted_message
)
{
if
(
x
==
CODE_decrypted_message
)
{
M
->
message
=
fetch_str_dup
();
M
->
message
=
fetch_str_dup
();
fetch_
encrypted_message_file
(
&
M
->
media
);
fetch_
message_media_encrypted
(
&
M
->
media
);
}
else
{
}
else
{
assert
(
fetch_int
()
==
(
int
)
CODE_decrypted_message_action_set_message_t_t_l
);
assert
(
fetch_int
()
==
(
int
)
CODE_decrypted_message_action_set_message_t_t_l
);
P
->
encr_chat
.
ttl
=
fetch_int
();
P
->
encr_chat
.
ttl
=
fetch_int
();
M
->
service
=
1
;
}
}
in_ptr
=
save_in_ptr
;
in_end
=
save_in_end
;
}
if
(
sx
==
CODE_encrypted_message
)
{
if
(
ok
)
{
fetch_encrypted_message_file
(
&
M
->
media
);
}
else
{
x
=
fetch_int
();
if
(
x
==
CODE_encrypted_file
)
{
fetch_skip
(
7
);
}
else
{
assert
(
x
==
CODE_encrypted_file_empty
);
}
M
->
media
.
type
=
CODE_message_media_empty
;
}
}
}
}
}
...
@@ -793,7 +891,8 @@ void fetch_encrypted_message_file (struct message_media *M) {
...
@@ -793,7 +891,8 @@ void fetch_encrypted_message_file (struct message_media *M) {
assert
(
M
->
type
==
CODE_decrypted_message_media_photo
||
M
->
type
==
CODE_decrypted_message_media_video
);
assert
(
M
->
type
==
CODE_decrypted_message_media_photo
||
M
->
type
==
CODE_decrypted_message_media_video
);
M
->
encr_photo
.
id
=
fetch_long
();
M
->
encr_photo
.
id
=
fetch_long
();
M
->
encr_photo
.
access_hash
=
fetch_long
();
M
->
encr_photo
.
access_hash
=
fetch_long
();
assert
(
M
->
encr_photo
.
size
==
fetch_int
());
//assert (M->encr_photo.size == fetch_int ());
M
->
encr_photo
.
size
=
fetch_int
();
// Why it is not the same?
M
->
encr_photo
.
dc_id
=
fetch_int
();
M
->
encr_photo
.
dc_id
=
fetch_int
();
M
->
encr_photo
.
key_fingerprint
=
fetch_int
();
M
->
encr_photo
.
key_fingerprint
=
fetch_int
();
...
@@ -813,8 +912,6 @@ DEFINE_TREE(message,struct message *,id_cmp,0)
...
@@ -813,8 +912,6 @@ DEFINE_TREE(message,struct message *,id_cmp,0)
struct
tree_peer
*
peer_tree
;
struct
tree_peer
*
peer_tree
;
struct
tree_message
*
message_tree
;
struct
tree_message
*
message_tree
;
int
chat_num
;
int
user_num
;
int
users_allocated
;
int
users_allocated
;
int
chats_allocated
;
int
chats_allocated
;
int
messages_allocated
;
int
messages_allocated
;
...
@@ -837,7 +934,7 @@ struct user *fetch_alloc_user (void) {
...
@@ -837,7 +934,7 @@ struct user *fetch_alloc_user (void) {
memset
(
U
,
0
,
sizeof
(
*
U
));
memset
(
U
,
0
,
sizeof
(
*
U
));
fetch_user
(
&
U
->
user
);
fetch_user
(
&
U
->
user
);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
Peers
[
chat_num
+
(
user_num
++
)
]
=
U
;
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
user
;
return
&
U
->
user
;
}
}
}
}
...
@@ -850,16 +947,22 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) {
...
@@ -850,16 +947,22 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) {
fetch_encrypted_chat
(
&
U
->
encr_chat
);
fetch_encrypted_chat
(
&
U
->
encr_chat
);
return
&
U
->
encr_chat
;
return
&
U
->
encr_chat
;
}
else
{
}
else
{
chats_allocated
++
;
encr_
chats_allocated
++
;
U
=
malloc
(
sizeof
(
*
U
));
U
=
malloc
(
sizeof
(
*
U
));
memset
(
U
,
0
,
sizeof
(
*
U
));
memset
(
U
,
0
,
sizeof
(
*
U
));
fetch_encrypted_chat
(
&
U
->
encr_chat
);
fetch_encrypted_chat
(
&
U
->
encr_chat
);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
Peers
[
(
chat_num
++
)
+
user_num
]
=
U
;
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
encr_chat
;
return
&
U
->
encr_chat
;
}
}
}
}
void
insert_encrypted_chat
(
peer_t
*
P
)
{
encr_chats_allocated
++
;
peer_tree
=
tree_insert_peer
(
peer_tree
,
P
,
lrand48
());
Peers
[
peer_num
++
]
=
P
;
}
struct
user
*
fetch_alloc_user_full
(
void
)
{
struct
user
*
fetch_alloc_user_full
(
void
)
{
int
data
[
3
];
int
data
[
3
];
prefetch_data
(
data
,
12
);
prefetch_data
(
data
,
12
);
...
@@ -874,7 +977,7 @@ struct user *fetch_alloc_user_full (void) {
...
@@ -874,7 +977,7 @@ struct user *fetch_alloc_user_full (void) {
U
->
id
=
MK_USER
(
data
[
2
]);
U
->
id
=
MK_USER
(
data
[
2
]);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
fetch_user_full
(
&
U
->
user
);
fetch_user_full
(
&
U
->
user
);
Peers
[
chat_num
+
(
user_num
++
)
]
=
U
;
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
user
;
return
&
U
->
user
;
}
}
}
}
...
@@ -938,6 +1041,8 @@ void free_message_media (struct message_media *M) {
...
@@ -938,6 +1041,8 @@ void free_message_media (struct message_media *M) {
free
(
M
->
encr_video
.
key
);
free
(
M
->
encr_video
.
key
);
free
(
M
->
encr_video
.
iv
);
free
(
M
->
encr_video
.
iv
);
return
;
return
;
case
0
:
break
;
default:
default:
logprintf
(
"%08x
\n
"
,
M
->
type
);
logprintf
(
"%08x
\n
"
,
M
->
type
);
assert
(
0
);
assert
(
0
);
...
@@ -964,6 +1069,8 @@ void free_message_action (struct message_action *M) {
...
@@ -964,6 +1069,8 @@ void free_message_action (struct message_action *M) {
break
;
break
;
case
CODE_message_action_chat_delete_user
:
case
CODE_message_action_chat_delete_user
:
break
;
break
;
case
0
:
break
;
default:
default:
assert
(
0
);
assert
(
0
);
}
}
...
@@ -990,6 +1097,61 @@ void message_add_use (struct message *M) {
...
@@ -990,6 +1097,61 @@ void message_add_use (struct message *M) {
M
->
prev_use
->
next_use
=
M
;
M
->
prev_use
->
next_use
=
M
;
}
}
void
message_add_peer
(
struct
message
*
M
)
{
peer_id_t
id
;
if
(
!
cmp_peer_id
(
M
->
to_id
,
MK_USER
(
our_id
)))
{
id
=
M
->
from_id
;
}
else
{
id
=
M
->
to_id
;
}
peer_t
*
P
=
user_chat_get
(
id
);
if
(
!
P
)
{
P
=
malloc
(
sizeof
(
*
P
));
memset
(
P
,
0
,
sizeof
(
*
P
));
P
->
id
=
id
;
P
->
flags
=
FLAG_EMPTY
;
switch
(
get_peer_type
(
id
))
{
case
PEER_USER
:
users_allocated
++
;
break
;
case
PEER_CHAT
:
chats_allocated
++
;
break
;
case
PEER_GEO_CHAT
:
geo_chats_allocated
++
;
break
;
case
PEER_ENCR_CHAT
:
encr_chats_allocated
++
;
break
;
}
peer_tree
=
tree_insert_peer
(
peer_tree
,
P
,
lrand48
());
Peers
[
peer_num
++
]
=
P
;
}
M
->
next
=
P
->
last
;
if
(
M
->
next
)
{
M
->
next
->
prev
=
M
;
}
M
->
prev
=
0
;
P
->
last
=
M
;
}
void
message_del_peer
(
struct
message
*
M
)
{
peer_id_t
id
;
if
(
!
cmp_peer_id
(
M
->
to_id
,
MK_USER
(
our_id
)))
{
id
=
M
->
from_id
;
}
else
{
id
=
M
->
to_id
;
}
peer_t
*
P
=
user_chat_get
(
id
);
if
(
M
->
prev
)
{
M
->
prev
->
next
=
M
->
next
;
}
if
(
M
->
next
)
{
M
->
next
->
prev
=
M
->
prev
;
}
if
(
P
&&
P
->
last
==
M
)
{
P
->
last
=
M
->
next
;
}
}
struct
message
*
fetch_alloc_message
(
void
)
{
struct
message
*
fetch_alloc_message
(
void
)
{
struct
message
*
M
=
malloc
(
sizeof
(
*
M
));
struct
message
*
M
=
malloc
(
sizeof
(
*
M
));
fetch_message
(
M
);
fetch_message
(
M
);
...
@@ -997,14 +1159,17 @@ struct message *fetch_alloc_message (void) {
...
@@ -997,14 +1159,17 @@ struct message *fetch_alloc_message (void) {
messages_allocated
++
;
messages_allocated
++
;
if
(
M1
)
{
if
(
M1
)
{
message_del_use
(
M1
);
message_del_use
(
M1
);
message_del_peer
(
M1
);
free_message
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
free
(
M
);
message_add_use
(
M1
);
message_add_use
(
M1
);
message_add_peer
(
M1
);
messages_allocated
--
;
messages_allocated
--
;
return
M1
;
return
M1
;
}
else
{
}
else
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
return
M
;
}
}
...
@@ -1017,14 +1182,17 @@ struct message *fetch_alloc_geo_message (void) {
...
@@ -1017,14 +1182,17 @@ struct message *fetch_alloc_geo_message (void) {
messages_allocated
++
;
messages_allocated
++
;
if
(
M1
)
{
if
(
M1
)
{
message_del_use
(
M1
);
message_del_use
(
M1
);
message_del_peer
(
M1
);
free_message
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
free
(
M
);
message_add_use
(
M1
);
message_add_use
(
M1
);
message_add_peer
(
M1
);
messages_allocated
--
;
messages_allocated
--
;
return
M1
;
return
M1
;
}
else
{
}
else
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
return
M
;
}
}
...
@@ -1037,14 +1205,17 @@ struct message *fetch_alloc_encrypted_message (void) {
...
@@ -1037,14 +1205,17 @@ struct message *fetch_alloc_encrypted_message (void) {
messages_allocated
++
;
messages_allocated
++
;
if
(
M1
)
{
if
(
M1
)
{
message_del_use
(
M1
);
message_del_use
(
M1
);
message_del_peer
(
M1
);
free_message
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
free
(
M
);
message_add_use
(
M1
);
message_add_use
(
M1
);
message_add_peer
(
M1
);
messages_allocated
--
;
messages_allocated
--
;
return
M1
;
return
M1
;
}
else
{
}
else
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
return
M
;
}
}
...
@@ -1057,14 +1228,17 @@ struct message *fetch_alloc_message_short (void) {
...
@@ -1057,14 +1228,17 @@ struct message *fetch_alloc_message_short (void) {
messages_allocated
++
;
messages_allocated
++
;
if
(
M1
)
{
if
(
M1
)
{
message_del_use
(
M1
);
message_del_use
(
M1
);
message_del_peer
(
M1
);
free_message
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
free
(
M
);
message_add_use
(
M1
);
message_add_use
(
M1
);
message_add_peer
(
M1
);
messages_allocated
--
;
messages_allocated
--
;
return
M1
;
return
M1
;
}
else
{
}
else
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
return
M
;
}
}
...
@@ -1080,14 +1254,17 @@ struct message *fetch_alloc_message_short_chat (void) {
...
@@ -1080,14 +1254,17 @@ struct message *fetch_alloc_message_short_chat (void) {
messages_allocated
++
;
messages_allocated
++
;
if
(
M1
)
{
if
(
M1
)
{
message_del_use
(
M1
);
message_del_use
(
M1
);
message_del_peer
(
M1
);
free_message
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
free
(
M
);
message_add_use
(
M1
);
message_add_use
(
M1
);
message_add_peer
(
M1
);
messages_allocated
--
;
messages_allocated
--
;
return
M1
;
return
M1
;
}
else
{
}
else
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
return
M
;
}
}
...
@@ -1106,7 +1283,7 @@ struct chat *fetch_alloc_chat (void) {
...
@@ -1106,7 +1283,7 @@ struct chat *fetch_alloc_chat (void) {
memset
(
U
,
0
,
sizeof
(
*
U
));
memset
(
U
,
0
,
sizeof
(
*
U
));
fetch_chat
(
&
U
->
chat
);
fetch_chat
(
&
U
->
chat
);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
Peers
[
(
chat_num
++
)
+
user_num
]
=
U
;
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
chat
;
return
&
U
->
chat
;
}
}
}
}
...
@@ -1125,7 +1302,7 @@ struct chat *fetch_alloc_chat_full (void) {
...
@@ -1125,7 +1302,7 @@ struct chat *fetch_alloc_chat_full (void) {
U
->
id
=
MK_CHAT
(
data
[
2
]);
U
->
id
=
MK_CHAT
(
data
[
2
]);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
fetch_chat_full
(
&
U
->
chat
);
fetch_chat_full
(
&
U
->
chat
);
Peers
[
(
chat_num
++
)
+
user_num
]
=
U
;
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
chat
;
return
&
U
->
chat
;
}
}
}
}
...
@@ -1139,9 +1316,13 @@ int print_stat (char *s, int len) {
...
@@ -1139,9 +1316,13 @@ int print_stat (char *s, int len) {
return
snprintf
(
s
,
len
,
return
snprintf
(
s
,
len
,
"users_allocated
\t
%d
\n
"
"users_allocated
\t
%d
\n
"
"chats_allocated
\t
%d
\n
"
"chats_allocated
\t
%d
\n
"
"secret_chats_allocated
\t
%d
\n
"
"peer_num
\t
%d
\n
"
"messages_allocated
\t
%d
\n
"
,
"messages_allocated
\t
%d
\n
"
,
users_allocated
,
users_allocated
,
chats_allocated
,
chats_allocated
,
encr_chats_allocated
,
peer_num
,
messages_allocated
messages_allocated
);
);
}
}
...
@@ -1166,5 +1347,6 @@ void update_message_id (struct message *M, long long id) {
...
@@ -1166,5 +1347,6 @@ void update_message_id (struct message *M, long long id) {
void
message_insert
(
struct
message
*
M
)
{
void
message_insert
(
struct
message
*
M
)
{
message_add_use
(
M
);
message_add_use
(
M
);
message_add_peer
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
}
}
structures.h
View file @
923845d6
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#define __STRUCTURES_H__
#define __STRUCTURES_H__
#include <assert.h>
#include <assert.h>
typedef
struct
{
int
id
;
}
peer_id_t
;
typedef
struct
{
int
type
;
int
id
;
}
peer_id_t
;
#define FLAG_EMPTY 1
#define FLAG_EMPTY 1
#define FLAG_DELETED 2
#define FLAG_DELETED 2
...
@@ -111,6 +111,7 @@ struct user_status {
...
@@ -111,6 +111,7 @@ struct user_status {
struct
user
{
struct
user
{
peer_id_t
id
;
peer_id_t
id
;
int
flags
;
int
flags
;
struct
message
*
last
;
char
*
print_name
;
char
*
print_name
;
struct
file_location
photo_big
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
file_location
photo_small
;
...
@@ -134,6 +135,7 @@ struct chat_user {
...
@@ -134,6 +135,7 @@ struct chat_user {
struct
chat
{
struct
chat
{
peer_id_t
id
;
peer_id_t
id
;
int
flags
;
int
flags
;
struct
message
*
last
;
char
*
print_title
;
char
*
print_title
;
struct
file_location
photo_big
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
file_location
photo_small
;
...
@@ -157,6 +159,7 @@ enum secret_chat_state {
...
@@ -157,6 +159,7 @@ enum secret_chat_state {
struct
secret_chat
{
struct
secret_chat
{
peer_id_t
id
;
peer_id_t
id
;
int
flags
;
int
flags
;
struct
message
*
last
;
char
*
print_name
;
char
*
print_name
;
struct
file_location
photo_big
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
file_location
photo_small
;
...
@@ -178,6 +181,7 @@ typedef union peer {
...
@@ -178,6 +181,7 @@ typedef union peer {
struct
{
struct
{
peer_id_t
id
;
peer_id_t
id
;
int
flags
;
int
flags
;
struct
message
*
last
;
char
*
print_name
;
char
*
print_name
;
struct
file_location
photo_big
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
file_location
photo_small
;
...
@@ -237,6 +241,7 @@ struct message_media {
...
@@ -237,6 +241,7 @@ struct message_media {
struct
message
{
struct
message
{
struct
message
*
next_use
,
*
prev_use
;
struct
message
*
next_use
,
*
prev_use
;
struct
message
*
next
,
*
prev
;
long
long
id
;
long
long
id
;
int
flags
;
int
flags
;
peer_id_t
fwd_from_id
;
peer_id_t
fwd_from_id
;
...
@@ -283,6 +288,7 @@ void update_message_id (struct message *M, long long id);
...
@@ -283,6 +288,7 @@ void update_message_id (struct message *M, long long id);
void
message_insert
(
struct
message
*
M
);
void
message_insert
(
struct
message
*
M
);
void
free_photo
(
struct
photo
*
P
);
void
free_photo
(
struct
photo
*
P
);
void
fetch_photo
(
struct
photo
*
P
);
void
fetch_photo
(
struct
photo
*
P
);
void
insert_encrypted_chat
(
peer_t
*
P
);
#define PEER_USER 1
#define PEER_USER 1
#define PEER_CHAT 2
#define PEER_CHAT 2
...
@@ -296,55 +302,18 @@ void fetch_photo (struct photo *P);
...
@@ -296,55 +302,18 @@ void fetch_photo (struct photo *P);
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
static
inline
int
get_peer_type
(
peer_id_t
id
)
{
static
inline
int
get_peer_type
(
peer_id_t
id
)
{
if
(
id
.
id
>
1000000000
)
{
return
id
.
type
;
return
PEER_ENCR_CHAT
;
}
if
(
id
.
id
>
0
)
{
return
PEER_USER
;
}
if
(
id
.
id
<
-
1000000000
)
{
return
PEER_GEO_CHAT
;
}
if
(
id
.
id
<
0
)
{
return
PEER_CHAT
;
}
return
PEER_UNKNOWN
;
}
}
static
inline
int
get_peer_id
(
peer_id_t
id
)
{
static
inline
int
get_peer_id
(
peer_id_t
id
)
{
switch
(
get_peer_type
(
id
))
{
return
id
.
id
;
case
PEER_USER
:
return
id
.
id
;
case
PEER_CHAT
:
return
-
id
.
id
;
case
PEER_GEO_CHAT
:
return
-
id
.
id
-
1000000000
;
case
PEER_ENCR_CHAT
:
return
id
.
id
-
1000000000
;
default:
return
0
;
}
}
}
static
inline
peer_id_t
set_peer_id
(
int
type
,
int
id
)
{
static
inline
peer_id_t
set_peer_id
(
int
type
,
int
id
)
{
peer_id_t
ID
;
peer_id_t
ID
;
switch
(
type
)
{
ID
.
id
=
id
;
case
PEER_USER
:
ID
.
type
=
type
;
ID
.
id
=
id
;
return
ID
;
return
ID
;
case
PEER_CHAT
:
ID
.
id
=
-
id
;
return
ID
;
case
PEER_GEO_CHAT
:
ID
.
id
=
-
id
-
1000000000
;
return
ID
;
case
PEER_ENCR_CHAT
:
ID
.
id
=
id
+
1000000000
;
return
ID
;
default:
assert
(
0
);
return
ID
;
}
}
}
static
inline
int
cmp_peer_id
(
peer_id_t
a
,
peer_id_t
b
)
{
static
inline
int
cmp_peer_id
(
peer_id_t
a
,
peer_id_t
b
)
{
...
...
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