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
0061aa6d
Commit
0061aa6d
authored
Nov 15, 2013
by
vysheng
Browse files
Options
Browse Files
Download
Plain Diff
Merge github.com:vysheng/tg
parents
33d15ff1
62bc5c71
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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
#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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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
;
}
...
...
@@ -2143,6 +2191,8 @@ int send_encr_request_on_answer (struct query *q UU) {
printf
(
"
\n
"
);
pop_color
();
print_end
();
assert
(
E
->
state
==
sc_waiting
);
}
return
0
;
}
...
...
@@ -2186,10 +2236,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
);
...
...
@@ -2205,15 +2263,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
)
{
...
...
@@ -2242,6 +2307,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
)
{
...
...
@@ -2294,20 +2368,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
();
...
...
@@ -2441,7 +2531,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
)
{
...
...
@@ -2598,6 +2688,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 @
0061aa6d
...
...
@@ -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 @
0061aa6d
...
...
@@ -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
();
...
...
@@ -1031,13 +1100,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
;
...
...
@@ -1443,7 +1512,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 @
0061aa6d
...
...
@@ -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
...
...
@@ -138,6 +139,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
;
...
...
@@ -162,6 +164,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
;
...
...
@@ -186,6 +189,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
;
...
...
@@ -208,6 +212,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
;
...
...
@@ -314,9 +319,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
);
...
...
@@ -333,6 +338,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