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
8ad5053c
Commit
8ad5053c
authored
Nov 15, 2013
by
Vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Partial support for binlog. It now can track user, secret chat and auth updates.
parent
0d994828
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
584 additions
and
91 deletions
+584
-91
Makefile
Makefile
+1
-1
Makefile.in
Makefile.in
+1
-1
binlog.c
binlog.c
+212
-8
binlog.h
binlog.h
+17
-0
loop.c
loop.c
+16
-3
mtproto-client.c
mtproto-client.c
+46
-2
mtproto-common.h
mtproto-common.h
+47
-0
queries.c
queries.c
+101
-10
queries.h
queries.h
+1
-0
structures.c
structures.c
+132
-63
structures.h
structures.h
+10
-3
No files found.
Makefile
View file @
8ad5053c
...
...
@@ -7,7 +7,7 @@ DEFS=-DHAVE_CONFIG_H
COMPILE_FLAGS
=
${
CFLAGS
}
${
CPPFLAGS
}
${
DEFS
}
-Wall
-Wextra
-Werror
-Wno-deprecated
-fno-strict-aliasing
-fno-omit-frame-pointer
-ggdb
EXTRA_LIBS
=
-lreadline
-lrt
-lconfig
LOCAL_LDFLAGS
=
-lm
-lcrypto
-lz
-lssl
-rdynamic
${
EXTRA_LIBS
}
LOCAL_LDFLAGS
=
-lm
-lcrypto
-lz
-lssl
-rdynamic
-ggdb
${
EXTRA_LIBS
}
LINK_FLAGS
=
${
LDFLAGS
}
${
LOCAL_LDFLAGS
}
HEADERS
=
${
srcdir
}
/constants.h
${
srcdir
}
/include.h
${
srcdir
}
/interface.h
${
srcdir
}
/LICENSE.h
${
srcdir
}
/loop.h
${
srcdir
}
/mtproto-client.h
${
srcdir
}
/mtproto-common.h
${
srcdir
}
/net.h
${
srcdir
}
/no-preview.h
${
srcdir
}
/queries.h
${
srcdir
}
/structures.h
${
srcdir
}
/telegram.h
${
srcdir
}
/tree.h
${
srcdir
}
/config.h
${
srcdir
}
/binlog.h
...
...
Makefile.in
View file @
8ad5053c
...
...
@@ -7,7 +7,7 @@ DEFS=@DEFS@
COMPILE_FLAGS
=
${
CFLAGS
}
${
CPPFLAGS
}
${
DEFS
}
-Wall
-Wextra
-Werror
-Wno-deprecated
-fno-strict-aliasing
-fno-omit-frame-pointer
-ggdb
EXTRA_LIBS
=
@EXTRA_LIBS@
LOCAL_LDFLAGS
=
-lm
-lcrypto
-lz
-lssl
-rdynamic
${
EXTRA_LIBS
}
LOCAL_LDFLAGS
=
-lm
-lcrypto
-lz
-lssl
-rdynamic
-ggdb
${
EXTRA_LIBS
}
LINK_FLAGS
=
${
LDFLAGS
}
${
LOCAL_LDFLAGS
}
HEADERS
=
${
srcdir
}
/constants.h
${
srcdir
}
/include.h
${
srcdir
}
/interface.h
${
srcdir
}
/LICENSE.h
${
srcdir
}
/loop.h
${
srcdir
}
/mtproto-client.h
${
srcdir
}
/mtproto-common.h
${
srcdir
}
/net.h
${
srcdir
}
/no-preview.h
${
srcdir
}
/queries.h
${
srcdir
}
/structures.h
${
srcdir
}
/telegram.h
${
srcdir
}
/tree.h
${
srcdir
}
/config.h
${
srcdir
}
/binlog.h
...
...
binlog.c
View file @
8ad5053c
...
...
@@ -11,10 +11,7 @@
#include "binlog.h"
#include "mtproto-common.h"
#include "net.h"
#define LOG_START 0x8948329a
#define LOG_AUTH_KEY 0x984932aa
#define LOG_DEFAULT_DC 0x95382908
#include "include.h"
#define BINLOG_BUFFER_SIZE (1 << 20)
int
binlog_buffer
[
BINLOG_BUFFER_SIZE
];
...
...
@@ -28,6 +25,14 @@ char *get_binlog_file_name (void);
extern
struct
dc
*
DC_list
[];
extern
struct
dc
*
DC_working
;
extern
int
dc_working_num
;
extern
int
our_id
;
extern
int
binlog_enabled
;
int
in_replay_log
;
void
*
alloc_log_event
(
int
l
UU
)
{
return
binlog_buffer
;
}
void
replay_log_event
(
void
)
{
assert
(
rptr
<
wptr
);
...
...
@@ -41,6 +46,7 @@ void replay_log_event (void) {
return
;
case
CODE_dc_option
:
fetch_dc_option
();
rptr
=
in_ptr
;
return
;
case
LOG_AUTH_KEY
:
rptr
++
;
...
...
@@ -52,6 +58,7 @@ void replay_log_event (void) {
rptr
+=
2
;
memcpy
(
DC_list
[
num
]
->
auth_key
,
rptr
,
256
);
rptr
+=
64
;
DC_list
[
num
]
->
flags
|=
1
;
};
return
;
case
LOG_DEFAULT_DC
:
...
...
@@ -63,6 +70,180 @@ void replay_log_event (void) {
dc_working_num
=
num
;
}
return
;
case
LOG_OUR_ID
:
rptr
++
;
{
our_id
=
*
(
rptr
++
);
}
break
;
case
LOG_DC_SIGNED
:
rptr
++
;
{
int
num
=
*
(
rptr
++
);
assert
(
num
>=
0
&&
num
<=
MAX_DC_ID
);
assert
(
DC_list
[
num
]);
DC_list
[
num
]
->
has_auth
=
1
;
}
break
;
case
LOG_DC_SALT
:
rptr
++
;
{
int
num
=
*
(
rptr
++
);
assert
(
num
>=
0
&&
num
<=
MAX_DC_ID
);
assert
(
DC_list
[
num
]);
DC_list
[
num
]
->
server_salt
=
*
(
long
long
*
)
rptr
;
rptr
+=
2
;
};
break
;
case
CODE_user_empty
:
case
CODE_user_self
:
case
CODE_user_contact
:
case
CODE_user_request
:
case
CODE_user_foreign
:
case
CODE_user_deleted
:
fetch_alloc_user
();
rptr
=
in_ptr
;
return
;
case
LOG_DH_CONFIG
:
get_dh_config_on_answer
(
0
);
rptr
=
in_ptr
;
return
;
case
LOG_ENCR_CHAT_KEY
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
assert
(
U
);
U
->
key_fingerprint
=
*
(
long
long
*
)
rptr
;
rptr
+=
2
;
memcpy
(
U
->
key
,
rptr
,
256
);
rptr
+=
64
;
};
return
;
case
LOG_ENCR_CHAT_SEND_ACCEPT
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
assert
(
U
);
U
->
key_fingerprint
=
*
(
long
long
*
)
rptr
;
rptr
+=
2
;
memcpy
(
U
->
key
,
rptr
,
256
);
rptr
+=
64
;
if
(
!
U
->
g_key
)
{
U
->
g_key
=
malloc
(
256
);
}
memcpy
(
U
->
g_key
,
rptr
,
256
);
rptr
+=
64
;
};
return
;
case
LOG_ENCR_CHAT_SEND_CREATE
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
assert
(
!
U
||
(
U
->
flags
&
FLAG_EMPTY
));
if
(
!
U
)
{
U
=
malloc
(
sizeof
(
peer_t
));
memset
(
U
,
0
,
sizeof
(
peer_t
));
U
->
id
=
id
;
insert_encrypted_chat
((
void
*
)
U
);
}
else
{
U
->
flags
&=
~
FLAG_EMPTY
;
}
U
->
flags
|=
FLAG_CREATED
;
U
->
user_id
=
*
(
rptr
++
);
memcpy
(
U
->
key
,
rptr
,
256
);
rptr
+=
64
;
if
(
!
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
);
}
}
};
return
;
case
LOG_ENCR_CHAT_DELETED
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
if
(
!
U
)
{
U
=
malloc
(
sizeof
(
peer_t
));
memset
(
U
,
0
,
sizeof
(
peer_t
));
U
->
id
=
id
;
insert_encrypted_chat
((
void
*
)
U
);
}
else
{
U
->
flags
&=
~
FLAG_EMPTY
;
}
U
->
flags
|=
FLAG_CREATED
;
U
->
state
=
sc_deleted
;
};
return
;
case
LOG_ENCR_CHAT_WAITING
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
assert
(
U
);
U
->
state
=
sc_waiting
;
U
->
date
=
*
(
rptr
++
);
U
->
admin_id
=
*
(
rptr
++
);
U
->
user_id
=
*
(
rptr
++
);
U
->
access_hash
=
*
(
long
long
*
)
rptr
;
rptr
+=
2
;
};
return
;
case
LOG_ENCR_CHAT_REQUESTED
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
if
(
!
U
)
{
U
=
malloc
(
sizeof
(
peer_t
));
memset
(
U
,
0
,
sizeof
(
peer_t
));
U
->
id
=
id
;
insert_encrypted_chat
((
void
*
)
U
);
}
else
{
U
->
flags
&=
~
FLAG_EMPTY
;
}
U
->
flags
|=
FLAG_CREATED
;
U
->
state
=
sc_request
;
U
->
date
=
*
(
rptr
++
);
U
->
admin_id
=
*
(
rptr
++
);
U
->
user_id
=
*
(
rptr
++
);
U
->
access_hash
=
*
(
long
long
*
)
rptr
;
if
(
!
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
);
}
}
rptr
+=
2
;
};
return
;
case
LOG_ENCR_CHAT_OK
:
rptr
++
;
{
peer_id_t
id
=
MK_ENCR_CHAT
(
*
(
rptr
++
));
struct
secret_chat
*
U
=
(
void
*
)
user_chat_get
(
id
);
assert
(
U
);
U
->
state
=
sc_ok
;
}
return
;
default:
logprintf
(
"Unknown logevent [0x%08x] 0x%08x [0x%08x]
\n
"
,
*
(
rptr
-
1
),
op
,
*
(
rptr
+
1
));
assert
(
0
);
}
}
...
...
@@ -71,20 +252,27 @@ void create_new_binlog (void) {
packet_ptr
=
s
;
out_int
(
LOG_START
);
out_int
(
CODE_dc_option
);
out_int
(
0
);
out_int
(
1
);
out_string
(
""
);
out_string
(
test_dc
?
TG_SERVER_TEST
:
TG_SERVER
);
out_int
(
443
);
out_int
(
LOG_DEFAULT_DC
);
out_int
(
1
);
int
fd
=
open
(
get_binlog_file_name
(),
O_WRONLY
|
O_EXCL
);
int
fd
=
open
(
get_binlog_file_name
(),
O_WRONLY
|
O_EXCL
|
O_CREAT
,
0600
);
if
(
fd
<
0
)
{
perror
(
"Write new binlog"
);
exit
(
2
);
}
assert
(
write
(
fd
,
s
,
(
packet_ptr
-
s
)
*
4
)
==
(
packet_ptr
-
s
)
*
4
);
close
(
fd
);
}
void
replay_log
(
void
)
{
in_replay_log
=
1
;
if
(
access
(
get_binlog_file_name
(),
F_OK
)
<
0
)
{
printf
(
"No binlog found. Creating new one"
);
printf
(
"No binlog found. Creating new one
\n
"
);
create_new_binlog
();
}
int
fd
=
open
(
get_binlog_file_name
(),
O_RDONLY
);
...
...
@@ -92,7 +280,7 @@ void replay_log (void) {
perror
(
"binlog open"
);
exit
(
2
);
}
int
end
;
int
end
=
0
;
while
(
1
)
{
if
(
!
end
&&
wptr
-
rptr
<
MAX_LOG_EVENT_SIZE
/
4
)
{
if
(
wptr
==
rptr
)
{
...
...
@@ -119,4 +307,20 @@ void replay_log (void) {
replay_log_event
();
}
close
(
fd
);
in_replay_log
=
0
;
}
int
binlog_fd
;
void
write_binlog
(
void
)
{
binlog_fd
=
open
(
get_binlog_file_name
(),
O_WRONLY
);
if
(
binlog_fd
<
0
)
{
perror
(
"binlog open"
);
exit
(
2
);
}
lseek
(
binlog_fd
,
0
,
SEEK_END
);
}
void
add_log_event
(
const
int
*
data
,
int
len
)
{
if
(
in_replay_log
)
{
return
;
}
assert
(
write
(
binlog_fd
,
data
,
len
)
==
len
);
}
binlog.h
View file @
8ad5053c
#ifndef __BINLOG_H__
#define __BINLOG_H__
#define LOG_START 0x8948329a
#define LOG_AUTH_KEY 0x984932aa
#define LOG_DEFAULT_DC 0x95382908
#define LOG_OUR_ID 0x8943211a
#define LOG_DC_SIGNED 0x234f9893
#define LOG_DC_SALT 0x92192ffa
#define LOG_DH_CONFIG 0x8983402b
#define LOG_ENCR_CHAT_KEY 0x894320aa
#define LOG_ENCR_CHAT_SEND_ACCEPT 0x12ab01c4
#define LOG_ENCR_CHAT_SEND_CREATE 0xab091e24
#define LOG_ENCR_CHAT_DELETED 0x99481230
#define LOG_ENCR_CHAT_WAITING 0x7102100a
#define LOG_ENCR_CHAT_REQUESTED 0x9011011a
#define LOG_ENCR_CHAT_OK 0x7612ce13
void
*
alloc_log_event
(
int
l
);
void
replay_log
(
void
);
void
add_log_event
(
const
int
*
data
,
int
l
);
void
write_binlog
(
void
);
#endif
loop.c
View file @
8ad5053c
...
...
@@ -160,6 +160,7 @@ void write_dc (int auth_file_fd, struct dc *DC) {
int
our_id
;
void
write_auth_file
(
void
)
{
if
(
binlog_enabled
)
{
return
;
}
int
auth_file_fd
=
open
(
get_auth_key_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
assert
(
auth_file_fd
>=
0
);
int
x
=
DC_SERIALIZED_MAGIC_V2
;
...
...
@@ -216,6 +217,7 @@ void empty_auth_file (void) {
int
need_dc_list_update
;
void
read_auth_file
(
void
)
{
if
(
binlog_enabled
)
{
return
;
}
int
auth_file_fd
=
open
(
get_auth_key_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
auth_file_fd
<
0
)
{
empty_auth_file
();
...
...
@@ -308,6 +310,7 @@ extern unsigned char *encr_prime;
extern
int
encr_param_version
;
void
read_secret_chat_file
(
void
)
{
if
(
binlog_enabled
)
{
return
;
}
int
fd
=
open
(
get_secret_chat_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
fd
<
0
)
{
return
;
...
...
@@ -364,6 +367,7 @@ void read_secret_chat_file (void) {
}
void
write_secret_chat_file
(
void
)
{
if
(
binlog_enabled
)
{
return
;
}
int
fd
=
open
(
get_secret_chat_filename
(),
O_CREAT
|
O_RDWR
,
0600
);
if
(
fd
<
0
)
{
return
;
...
...
@@ -430,12 +434,15 @@ int loop (void) {
on_start
();
if
(
binlog_enabled
)
{
replay_log
();
write_binlog
();
}
else
{
read_auth_file
();
}
read_auth_file
();
update_prompt
();
assert
(
DC_list
[
dc_working_num
]);
if
(
auth_state
==
0
)
{
if
(
!
DC_working
||
!
DC_working
->
auth_key_id
)
{
// if (auth_state == 0) {
DC_working
=
DC_list
[
dc_working_num
];
assert
(
!
DC_working
->
auth_key_id
);
dc_authorize
(
DC_working
);
...
...
@@ -459,7 +466,7 @@ int loop (void) {
write_auth_file
();
}
if
(
auth_state
==
100
)
{
if
(
auth_state
==
100
||
!
(
DC_working
->
has_auth
)
)
{
if
(
!
default_username
)
{
size_t
size
=
0
;
char
*
user
=
0
;
...
...
@@ -546,6 +553,12 @@ int loop (void) {
do_export_auth
(
i
);
do_import_auth
(
i
);
DC_list
[
i
]
->
has_auth
=
1
;
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_DC_SIGNED
;
ev
[
1
]
=
i
;
add_log_event
(
ev
,
8
);
}
write_auth_file
();
}
write_auth_file
();
...
...
mtproto-client.c
View file @
8ad5053c
...
...
@@ -44,6 +44,7 @@
#include "loop.h"
#include "interface.h"
#include "structures.h"
#include "binlog.h"
#define sha1 SHA1
...
...
@@ -57,6 +58,7 @@ enum dc_state c_state;
char
nonce
[
256
];
char
new_nonce
[
256
];
char
server_nonce
[
256
];
extern
int
binlog_enabled
;
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
);
int
rpc_becomes_ready
(
struct
connection
*
c
);
...
...
@@ -509,6 +511,13 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
sha1
(
tmp
,
41
,
sha1_buffer
);
assert
(
!
memcmp
(
packet
+
56
,
sha1_buffer
+
4
,
16
));
GET_DC
(
c
)
->
server_salt
=
*
(
long
long
*
)
server_nonce
^
*
(
long
long
*
)
new_nonce
;
/* if (binlog_enabled) {
int *ev = alloc_log_event (16);
ev[0] = LOG_DC_SALT;
ev[1] = GET_DC(c)->id;
*(long long *)(ev + 2) = GET_DC(c)->server_salt;
add_log_event (ev, 16);
}*/
if
(
verbosity
>=
3
)
{
logprintf
(
"auth_key_id=%016llx
\n
"
,
GET_DC
(
c
)
->
auth_key_id
);
}
...
...
@@ -525,6 +534,15 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
auth_success
++
;
GET_DC
(
c
)
->
flags
|=
1
;
write_auth_file
();
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
+
8
+
256
);
ev
[
0
]
=
LOG_AUTH_KEY
;
ev
[
1
]
=
GET_DC
(
c
)
->
id
;
*
(
long
long
*
)(
ev
+
2
)
=
GET_DC
(
c
)
->
auth_key_id
;
memcpy
(
ev
+
4
,
GET_DC
(
c
)
->
auth_key
,
256
);
add_log_event
(
ev
,
8
+
8
+
256
);
}
return
1
;
}
...
...
@@ -559,7 +577,7 @@ void init_enc_msg (struct session *S, int useful) {
struct
dc
*
DC
=
S
->
dc
;
assert
(
DC
->
auth_key_id
);
enc_msg
.
auth_key_id
=
DC
->
auth_key_id
;
assert
(
DC
->
server_salt
);
//
assert (DC->server_salt);
enc_msg
.
server_salt
=
DC
->
server_salt
;
if
(
!
S
->
session_id
)
{
assert
(
RAND_pseudo_bytes
((
unsigned
char
*
)
&
S
->
session_id
,
8
)
>=
0
);
...
...
@@ -1213,6 +1231,14 @@ void work_new_session_created (struct connection *c, long long msg_id UU) {
//DC->session_id = fetch_long ();
fetch_long
();
// unique_id
GET_DC
(
c
)
->
server_salt
=
fetch_long
();
/* if (binlog_enabled) {
int *ev = alloc_log_event (16);
ev[0] = LOG_DC_SALT;
ev[1] = GET_DC(c)->id;
*(long long *)(ev + 2) = GET_DC(c)->server_salt;
add_log_event (ev, 16);
}*/
}
void
work_msgs_ack
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
...
...
@@ -1294,6 +1320,13 @@ void work_bad_server_salt (struct connection *c UU, long long msg_id UU) {
fetch_int
();
// error_code
long
long
new_server_salt
=
fetch_long
();
GET_DC
(
c
)
->
server_salt
=
new_server_salt
;
/* if (binlog_enabled) {
int *ev = alloc_log_event (16);
ev[0] = LOG_DC_SALT;
ev[1] = GET_DC(c)->id;
*(long long *)(ev + 2) = GET_DC(c)->server_salt;
add_log_event (ev, 16);
}*/
}
void
work_pong
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
...
...
@@ -1389,6 +1422,13 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
if
(
DC
->
server_salt
!=
enc
->
server_salt
)
{
DC
->
server_salt
=
enc
->
server_salt
;
write_auth_file
();
/* if (binlog_enabled) {
int *ev = alloc_log_event (16);
ev[0] = LOG_DC_SALT;
ev[1] = DC->id;
*(long long *)(ev + 2) = DC->server_salt;
add_log_event (ev, 16);
}*/
}
int
this_server_time
=
enc
->
msg_id
>>
32LL
;
...
...
@@ -1475,7 +1515,11 @@ int rpc_execute (struct connection *c, int op, int len) {
#endif
return
0
;
case
st_authorized
:
process_rpc_message
(
c
,
(
void
*
)(
Response
/* + 8*/
),
Response_len
/* - 12*/
);
if
(
op
<
0
&&
op
>=
-
999
)
{
logprintf
(
"Server error %d
\n
"
,
op
);
}
else
{
process_rpc_message
(
c
,
(
void
*
)(
Response
/* + 8*/
),
Response_len
/* - 12*/
);
}
#ifndef __MACH__
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
#endif
...
...
mtproto-common.h
View file @
8ad5053c
...
...
@@ -307,6 +307,53 @@ static inline char *fetch_str_dup (void) {
return
s
;
}
static
inline
int
fetch_update_str
(
char
**
s
)
{
if
(
!*
s
)
{
*
s
=
fetch_str_dup
();
return
1
;
}
int
l
=
prefetch_strlen
();
char
*
r
=
fetch_str
(
l
);
if
(
memcmp
(
*
s
,
r
,
l
)
||
(
*
s
)[
l
])
{
free
(
*
s
);
*
s
=
malloc
(
l
+
1
);
memcpy
(
*
s
,
r
,
l
);
(
*
s
)[
l
]
=
0
;
return
1
;
}
return
0
;
}
static
inline
int
fetch_update_int
(
int
*
value
)
{
if
(
*
value
==
*
in_ptr
)
{
in_ptr
++
;
return
0
;
}
else
{
*
value
=
*
(
in_ptr
++
);
return
1
;
}
}
static
inline
int
fetch_update_long
(
long
long
*
value
)
{
if
(
*
value
==
*
(
long
long
*
)
in_ptr
)
{
in_ptr
+=
2
;
return
0
;
}
else
{
*
value
=
*
(
long
long
*
)(
in_ptr
);
in_ptr
+=
2
;
return
1
;
}
}
static
inline
int
set_update_int
(
int
*
value
,
int
new_value
)
{
if
(
*
value
==
new_value
)
{
return
0
;
}
else
{
*
value
=
new_value
;
return
1
;
}
}
static
inline
void
fetch_skip
(
int
n
)
{
in_ptr
+=
n
;
}
...
...
queries.c
View file @
8ad5053c
...
...
@@ -44,6 +44,7 @@
#include <openssl/md5.h>
#include "no-preview.h"
#include "binlog.h"
#define sha1 SHA1
...
...
@@ -55,6 +56,8 @@ long long cur_uploaded_bytes;
long
long
cur_downloading_bytes
;
long
long
cur_downloaded_bytes
;
extern
int
binlog_enabled
;
void
out_peer_id
(
peer_id_t
id
);
#define QUERY_TIMEOUT 6.0
...
...
@@ -303,6 +306,7 @@ void out_random (int n) {
/* {{{ Get config */
void
fetch_dc_option
(
void
)
{
int
*
start
=
in_ptr
;
assert
(
fetch_int
()
==
CODE_dc_option
);
int
id
=
fetch_int
();
int
l1
=
prefetch_strlen
();
...
...
@@ -316,6 +320,9 @@ void fetch_dc_option (void) {
if
(
!
DC_list
[
id
])
{
alloc_dc
(
id
,
strndup
(
ip
,
l2
),
port
);
new_dc_num
++
;
if
(
binlog_enabled
)
{
add_log_event
(
start
,
4
*
(
in_ptr
-
start
));
}
}
}
...
...
@@ -424,6 +431,13 @@ void do_send_code (const char *user) {
dc_create_session
(
DC_working
);
}
dc_working_num
=
want_dc_num
;
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_DEFAULT_DC
;
ev
[
1
]
=
dc_working_num
;
add_log_event
(
ev
,
8
);
}
logprintf
(
"send_code: dc_num = %d
\n
"
,
dc_working_num
);
want_dc_num
=
0
;
clear_packet
();
...
...
@@ -463,11 +477,27 @@ int check_phone_on_error (struct query *q UU, int error_code, int l, char *error
dc_working_num
=
i
;
DC_working
=
DC_list
[
i
];
write_auth_file
();
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_DEFAULT_DC
;
ev
[
1
]
=
i
;
add_log_event
(
ev
,
8
);
}
check_phone_result
=
1
;
}
else
if
(
l
>=
s2
&&
!
memcmp
(
error
,
"NETWORK_MIGRATE_"
,
s2
))
{
int
i
=
error
[
s2
]
-
'0'
;
assert
(
DC_list
[
i
]);
dc_working_num
=
i
;
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_DEFAULT_DC
;
ev
[
1
]
=
i
;
add_log_event
(
ev
,
8
);
}
DC_working
=
DC_list
[
i
];
write_auth_file
();
check_phone_result
=
1
;
...
...
@@ -536,6 +566,7 @@ int do_get_nearest_dc (void) {
/* {{{ Sign in / Sign up */
int
sign_in_ok
;
int
our_id
;
int
sign_in_is_ok
(
void
)
{
return
sign_in_ok
;
}
...
...
@@ -546,11 +577,28 @@ int sign_in_on_answer (struct query *q UU) {
assert
(
fetch_int
()
==
(
int
)
CODE_auth_authorization
);
int
expires
=
fetch_int
();
fetch_user
(
&
User
);
if
(
!
our_id
)
{
our_id
=
get_peer_id
(
User
.
id
);
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_OUR_ID
;
ev
[
1
]
=
our_id
;
add_log_event
(
ev
,
8
);
}
}
sign_in_ok
=
1
;
if
(
verbosity
)
{
logprintf
(
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
}
DC_working
->
has_auth
=
1
;
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_DC_SIGNED
;
ev
[
1
]
=
DC_working
->
id
;
add_log_event
(
ev
,
8
);
}
return
0
;
}
...
...
@@ -734,7 +782,7 @@ void encr_finish (struct secret_chat *E) {
/* {{{ Seng msg (plain text) */
int
msg_send_encr_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_messages_sent_encrypted_message
);
log
printf
(
"Sent
\n
"
);
r
printf
(
"Sent
\n
"
);
struct
message
*
M
=
q
->
extra
;
M
->
date
=
fetch_int
();
message_insert
(
M
);
...
...
@@ -790,7 +838,7 @@ int msg_send_on_answer (struct query *q UU) {
print_end
();
}
}
log
printf
(
"Sent: id = %d
\n
"
,
id
);
r
printf
(
"Sent: id = %d
\n
"
,
id
);
return
0
;
}
...
...
@@ -2113,6 +2161,8 @@ int send_encr_request_on_answer (struct query *q UU) {
printf
(
"
\n
"
);
pop_color
();
print_end
();
assert
(
E
->
state
==
sc_waiting
);
}
return
0
;
}
...
...
@@ -2156,10 +2206,18 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) {
sha1
((
void
*
)
E
->
key
,
256
,
sha_buffer
);
E
->
key_fingerprint
=
*
(
long
long
*
)(
sha_buffer
+
12
);
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
+
8
+
256
);
ev
[
0
]
=
LOG_ENCR_CHAT_KEY
;
ev
[
1
]
=
get_peer_id
(
E
->
id
);
*
(
long
long
*
)(
ev
+
2
)
=
E
->
key_fingerprint
;
memcpy
(
ev
+
4
,
E
->
key
,
256
);
add_log_event
(
ev
,
8
+
8
+
256
);
}
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
);
...
...
@@ -2175,15 +2233,22 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) {
BN_clear_free
(
g_a
);
BN_clear_free
(
p
);
BN_clear_free
(
r
);
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
16
+
512
);
ev
[
0
]
=
LOG_ENCR_CHAT_SEND_ACCEPT
;
ev
[
1
]
=
get_peer_id
(
E
->
id
);
*
(
long
long
*
)(
ev
+
2
)
=
E
->
key_fingerprint
;
memcpy
(
ev
+
4
,
E
->
key
,
256
);
memcpy
(
ev
+
68
,
buf
,
256
);
add_log_event
(
ev
,
16
+
512
);
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
);
}
void
do_create_keys_end
(
struct
secret_chat
*
U
)
{
if
(
!
encr_prime
)
{
rprintf
(
COLOR_YELLOW
"Something failed in bad moment. Did not fail
\n
"
COLOR_NORMAL
);
return
;
}
assert
(
encr_prime
);
BIGNUM
*
g_b
=
BN_bin2bn
(
U
->
g_key
,
256
,
0
);
assert
(
g_b
);
if
(
!
ctx
)
{
...
...
@@ -2212,6 +2277,15 @@ void do_create_keys_end (struct secret_chat *U) {
BN_clear_free
(
g_b
);
BN_clear_free
(
r
);
BN_clear_free
(
a
);
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
+
8
+
256
);
ev
[
0
]
=
LOG_ENCR_CHAT_KEY
;
ev
[
1
]
=
get_peer_id
(
U
->
id
);
*
(
long
long
*
)(
ev
+
2
)
=
U
->
key_fingerprint
;
memcpy
(
ev
+
4
,
U
->
key
,
256
);
add_log_event
(
ev
,
8
+
8
+
256
);
}
}
void
do_send_create_encr_chat
(
struct
secret_chat
*
E
,
unsigned
char
*
random
)
{
...
...
@@ -2264,20 +2338,36 @@ void do_send_create_encr_chat (struct secret_chat *E, unsigned char *random) {
BN_clear_free
(
p
);
BN_clear_free
(
r
);
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
12
+
256
);
ev
[
0
]
=
LOG_ENCR_CHAT_SEND_CREATE
;
ev
[
1
]
=
get_peer_id
(
E
->
id
);
ev
[
2
]
=
E
->
user_id
;
memcpy
(
ev
+
3
,
E
->
key
,
256
);
add_log_event
(
ev
,
12
+
256
);
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_request_methods
,
E
);
}
int
get_dh_config_on_answer
(
struct
query
*
q
UU
)
{
int
*
start
=
in_ptr
;
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_messages_dh_config
||
x
==
CODE_messages_dh_config_not_modified
);
if
(
x
==
CODE_messages_dh_config
)
{
assert
(
x
==
CODE_messages_dh_config
||
x
==
CODE_messages_dh_config_not_modified
||
LOG_DH_CONFIG
);
if
(
x
==
CODE_messages_dh_config
||
x
==
LOG_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
();
if
(
binlog_enabled
)
{
*
start
=
LOG_DH_CONFIG
;
add_log_event
(
start
,
4
*
(
in_ptr
-
start
));
*
start
=
CODE_messages_dh_config
;
}
}
if
(
x
==
LOG_DH_CONFIG
)
{
return
0
;
}
int
l
=
prefetch_strlen
();
assert
(
l
==
256
);
unsigned
char
*
random
=
(
void
*
)
fetch_str_dup
();
...
...
@@ -2411,7 +2501,7 @@ struct query_methods get_difference_methods = {
void
do_get_difference
(
void
)
{
difference_got
=
0
;
clear_packet
();
out_int
(
CODE_invoke_with_layer
10
);
out_int
(
CODE_invoke_with_layer
9
);
out_int
(
CODE_init_connection
);
out_int
(
TG_APP_ID
);
if
(
allow_send_linux_version
)
{
...
...
@@ -2568,6 +2658,7 @@ void do_create_secret_chat (peer_id_t id) {
peer_t
*
U
=
user_chat_get
(
id
);
if
(
!
U
)
{
rprintf
(
"Can not create chat with unknown user
\n
"
);
return
;
}
peer_t
*
P
=
malloc
(
sizeof
(
*
P
));
...
...
queries.h
View file @
8ad5053c
...
...
@@ -111,5 +111,6 @@ void do_contacts_search (int limit, const char *s);
// For binlog
int
get_dh_config_on_answer
(
struct
query
*
q
);
void
fetch_dc_option
(
void
);
#endif
structures.c
View file @
8ad5053c
...
...
@@ -30,6 +30,7 @@
#include <openssl/aes.h>
#include <openssl/sha.h>
#include "queries.h"
#include "binlog.h"
#define sha1 SHA1
...
...
@@ -40,24 +41,37 @@ int peer_num;
int
encr_chats_allocated
;
int
geo_chats_allocated
;
void
fetch_file_location
(
struct
file_location
*
loc
)
{
extern
int
binlog_enabled
;
void
fetch_add_alloc_log_event
(
void
*
obj
,
int
(
*
f
)(
void
*
))
{
int
*
start
=
in_ptr
;
int
r
=
f
(
obj
);
if
(
binlog_enabled
&&
r
)
{
add_log_event
(
start
,
4
*
(
in_ptr
-
start
));
}
}
int
fetch_file_location
(
struct
file_location
*
loc
)
{
int
x
=
fetch_int
();
int
new
=
0
;
if
(
x
==
CODE_file_location_unavailable
)
{
loc
->
dc
=
-
1
;
loc
->
volume
=
fetch_long
(
);
loc
->
local_id
=
fetch_int
(
);
loc
->
secret
=
fetch_long
(
);
new
|=
set_update_int
(
&
loc
->
dc
,
-
1
)
;
new
|=
fetch_update_long
(
&
loc
->
volume
);
new
|=
fetch_update_int
(
&
loc
->
local_id
);
new
|=
fetch_update_long
(
&
loc
->
secret
);
}
else
{
assert
(
x
==
CODE_file_location
);
loc
->
dc
=
fetch_int
();
;
loc
->
volume
=
fetch_long
(
);
loc
->
local_id
=
fetch_int
(
);
loc
->
secret
=
fetch_long
(
);
new
|=
fetch_update_int
(
&
loc
->
dc
)
;
new
|=
fetch_update_long
(
&
loc
->
volume
);
new
|=
fetch_update_int
(
&
loc
->
local_id
);
new
|=
fetch_update_long
(
&
loc
->
secret
);
}
return
new
;
}
void
fetch_user_status
(
struct
user_status
*
S
)
{
int
fetch_user_status
(
struct
user_status
*
S
)
{
int
x
=
fetch_int
();
int
old
=
S
->
online
;
switch
(
x
)
{
case
CODE_user_status_empty
:
S
->
online
=
0
;
...
...
@@ -73,6 +87,7 @@ void fetch_user_status (struct user_status *S) {
default:
assert
(
0
);
}
return
(
old
==
S
->
online
);
}
int
our_id
;
...
...
@@ -134,72 +149,83 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
return
strdup
(
s
);
}
void
fetch_user
(
struct
user
*
U
)
{
int
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
((
U
->
flags
&
FLAG_CREATED
)
&&
x
==
CODE_user_empty
)
{
return
0
;
}
int
old_flags
=
U
->
flags
;
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
|
FLAG_USER_SELF
|
FLAG_USER_FOREIGN
|
FLAG_USER_CONTACT
|
FLAG_CREATED
);
if
(
x
==
CODE_user_empty
)
{
U
->
flags
|=
FLAG_EMPTY
;
return
;
return
0
;
}
U
->
flags
|=
FLAG_CREATED
;
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
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_OUR_ID
;
ev
[
1
]
=
our_id
;
add_log_event
(
ev
,
8
);
}
}
}
i
f
(
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
);
i
nt
need_update
=
0
;
need_update
|=
fetch_update_str
(
&
U
->
first_name
);
need_update
|=
fetch_update_str
(
&
U
->
last_name
);
if
(
need_update
)
{
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
U
->
print_name
=
create_print_name
(
U
->
id
,
U
->
first_name
,
U
->
last_name
,
0
,
0
);
}
if
(
x
==
CODE_user_deleted
)
{
U
->
flags
|=
FLAG_DELETED
;
return
;
}
if
(
x
==
CODE_user_self
)
{
U
->
flags
|=
FLAG_USER_SELF
;
}
else
{
U
->
access_hash
=
fetch_long
();
}
if
(
x
==
CODE_user_foreign
)
{
U
->
flags
|=
FLAG_USER_FOREIGN
;
U
->
phone
=
0
;
}
else
{
if
(
U
->
phone
)
{
free
(
U
->
phone
);
}
U
->
phone
=
fetch_str_dup
();
}
//logprintf ("name = %s, surname = %s, phone = %s\n", U->first_name, U->last_name, U->phone);
unsigned
y
=
fetch_int
();
//fprintf (stderr, "y = 0x%08x\n", y);
if
(
y
==
CODE_user_profile_photo_empty
)
{
U
->
photo_small
.
dc
=
-
2
;
U
->
photo_big
.
dc
=
-
2
;
}
else
{
assert
(
y
==
CODE_user_profile_photo
||
y
==
0x990d1493
);
if
(
y
==
CODE_user_profile_photo
)
{
if
(
x
==
CODE_user_self
)
{
U
->
flags
|=
FLAG_USER_SELF
;
}
else
{
need_update
|=
fetch_update_long
(
&
U
->
access_hash
);
}
if
(
x
==
CODE_user_foreign
)
{
U
->
flags
|=
FLAG_USER_FOREIGN
;
}
else
{
need_update
|=
fetch_update_str
(
&
U
->
phone
);
}
unsigned
y
=
fetch_int
();
if
(
y
==
CODE_user_profile_photo_empty
)
{
need_update
|=
set_update_int
(
&
U
->
photo_small
.
dc
,
-
2
);
need_update
|=
set_update_int
(
&
U
->
photo_big
.
dc
,
-
2
);
}
else
{
assert
(
y
==
CODE_user_profile_photo
);
fetch_long
();
need_update
|=
fetch_file_location
(
&
U
->
photo_small
);
need_update
|=
fetch_file_location
(
&
U
->
photo_big
);
}
fetch_user_status
(
&
U
->
status
);
if
(
x
==
CODE_user_self
)
{
fetch_bool
();
}
if
(
x
==
CODE_user_contact
)
{
U
->
flags
|=
FLAG_USER_CONTACT
;
}
fetch_file_location
(
&
U
->
photo_small
);
fetch_file_location
(
&
U
->
photo_big
);
}
fetch_user_status
(
&
U
->
status
);
if
(
x
==
CODE_user_self
)
{
fetch_bool
();
}
if
(
x
==
CODE_user_contact
)
{
U
->
flags
|=
FLAG_USER_CONTACT
;
}
need_update
|=
(
old_flags
!=
U
->
flags
);
return
need_update
;
}
void
fetch_encrypted_chat
(
struct
secret_chat
*
U
)
{
unsigned
x
=
fetch_int
();
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
());
if
((
U
->
flags
&
FLAG_CREATED
)
&&
x
==
CODE_encrypted_chat_empty
)
{
return
;
}
U
->
flags
&=
~
(
FLAG_EMPTY
|
FLAG_DELETED
);
enum
secret_chat_state
old_state
=
U
->
state
;
if
(
x
==
CODE_encrypted_chat_empty
)
{
...
...
@@ -210,11 +236,18 @@ void fetch_encrypted_chat (struct secret_chat *U) {
}
return
;
}
U
->
flags
|=
FLAG_CREATED
;
if
(
x
==
CODE_encrypted_chat_discarded
)
{
U
->
state
=
sc_deleted
;
U
->
flags
|=
FLAG_DELETED
;
if
(
U
->
state
!=
old_state
)
{
write_secret_chat_file
();
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_ENCR_CHAT_DELETED
;
ev
[
1
]
=
get_peer_id
(
U
->
id
);
add_log_event
(
ev
,
8
);
}
}
return
;
}
...
...
@@ -222,19 +255,31 @@ void fetch_encrypted_chat (struct secret_chat *U) {
U
->
date
=
fetch_int
();
U
->
admin_id
=
fetch_int
();
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
(
!
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
)
{
U
->
state
=
sc_waiting
;
if
(
old_state
!=
sc_waiting
)
{
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
28
);
ev
[
0
]
=
LOG_ENCR_CHAT_WAITING
;
ev
[
1
]
=
get_peer_id
(
U
->
id
);
ev
[
2
]
=
U
->
date
;
ev
[
3
]
=
U
->
admin_id
;
ev
[
4
]
=
U
->
user_id
;
*
(
long
long
*
)(
ev
+
5
)
=
U
->
access_hash
;
add_log_event
(
ev
,
28
);
}
}
}
else
if
(
x
==
CODE_encrypted_chat_requested
)
{
U
->
state
=
sc_request
;
if
(
!
U
->
g_key
)
{
...
...
@@ -259,6 +304,18 @@ void fetch_encrypted_chat (struct secret_chat *U) {
}
else
{
memcpy
(
U
->
nonce
,
s
+
(
l
-
256
),
256
);
}
if
(
old_state
!=
sc_request
)
{
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
28
);
ev
[
0
]
=
LOG_ENCR_CHAT_REQUESTED
;
ev
[
1
]
=
get_peer_id
(
U
->
id
);
ev
[
2
]
=
U
->
date
;
ev
[
3
]
=
U
->
admin_id
;
ev
[
4
]
=
U
->
user_id
;
*
(
long
long
*
)(
ev
+
5
)
=
U
->
access_hash
;
add_log_event
(
ev
,
28
);
}
}
}
else
{
U
->
state
=
sc_ok
;
if
(
!
U
->
g_key
)
{
...
...
@@ -291,6 +348,18 @@ void fetch_encrypted_chat (struct secret_chat *U) {
if
(
old_state
==
sc_waiting
)
{
do_create_keys_end
(
U
);
}
free
(
U
->
g_key
);
U
->
g_key
=
0
;
free
(
U
->
nonce
);
U
->
nonce
=
0
;
if
(
old_state
!=
sc_ok
)
{
if
(
binlog_enabled
)
{
int
*
ev
=
alloc_log_event
(
8
);
ev
[
0
]
=
LOG_ENCR_CHAT_OK
;
ev
[
1
]
=
get_peer_id
(
U
->
id
);
add_log_event
(
ev
,
8
);
}
}
}
if
(
U
->
state
!=
old_state
)
{
write_secret_chat_file
();
...
...
@@ -941,13 +1010,13 @@ struct user *fetch_alloc_user (void) {
prefetch_data
(
data
,
8
);
peer_t
*
U
=
user_chat_get
(
MK_USER
(
data
[
1
]));
if
(
U
)
{
fetch_
user
(
&
U
->
user
);
fetch_
add_alloc_log_event
(
&
U
->
user
,
(
void
*
)
fetch_
user
);
return
&
U
->
user
;
}
else
{
users_allocated
++
;
U
=
malloc
(
sizeof
(
*
U
));
memset
(
U
,
0
,
sizeof
(
*
U
));
fetch_
user
(
&
U
->
user
);
fetch_
add_alloc_log_event
(
&
U
->
user
,
(
void
*
)
fetch_
user
);
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
Peers
[
peer_num
++
]
=
U
;
return
&
U
->
user
;
...
...
@@ -1343,7 +1412,7 @@ int print_stat (char *s, int len) {
}
peer_t
*
user_chat_get
(
peer_id_t
id
)
{
peer_t
U
;
static
peer_t
U
;
U
.
id
=
id
;
return
tree_lookup_peer
(
peer_tree
,
&
U
);
}
...
...
structures.h
View file @
8ad5053c
...
...
@@ -26,6 +26,7 @@ typedef struct { int type; int id; } peer_id_t;
#define FLAG_DELETED 2
#define FLAG_FORBIDDEN 4
#define FLAG_HAS_PHOTO 8
#define FLAG_CREATED 16
#define FLAG_USER_SELF 128
#define FLAG_USER_FOREIGN 256
...
...
@@ -113,6 +114,7 @@ struct user {
int
flags
;
struct
message
*
last
;
char
*
print_name
;
int
structure_version
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
photo
photo
;
...
...
@@ -137,6 +139,7 @@ struct chat {
int
flags
;
struct
message
*
last
;
char
*
print_title
;
int
structure_version
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
photo
photo
;
...
...
@@ -161,6 +164,7 @@ struct secret_chat {
int
flags
;
struct
message
*
last
;
char
*
print_name
;
int
structure_version
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
photo
photo
;
...
...
@@ -183,6 +187,7 @@ typedef union peer {
int
flags
;
struct
message
*
last
;
char
*
print_name
;
int
structure_version
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
struct
photo
photo
;
...
...
@@ -262,9 +267,9 @@ struct message {
};
};
void
fetch_file_location
(
struct
file_location
*
loc
);
void
fetch_user_status
(
struct
user_status
*
S
);
void
fetch_user
(
struct
user
*
U
);
int
fetch_file_location
(
struct
file_location
*
loc
);
int
fetch_user_status
(
struct
user_status
*
S
);
int
fetch_user
(
struct
user
*
U
);
struct
user
*
fetch_alloc_user
(
void
);
struct
user
*
fetch_alloc_user_full
(
void
);
struct
chat
*
fetch_alloc_chat
(
void
);
...
...
@@ -281,6 +286,8 @@ peer_id_t fetch_peer_id (void);
void
free_user
(
struct
user
*
U
);
void
free_chat
(
struct
chat
*
U
);
char
*
create_print_name
(
peer_id_t
id
,
const
char
*
a1
,
const
char
*
a2
,
const
char
*
a3
,
const
char
*
a4
);
int
print_stat
(
char
*
s
,
int
len
);
peer_t
*
user_chat_get
(
peer_id_t
id
);
struct
message
*
message_get
(
long
long
id
);
...
...
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