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
bf291df3
Commit
bf291df3
authored
Oct 13, 2013
by
Vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many fixes. Now (maybe) works authorization and get contact list query
parent
3243c29a
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
276 additions
and
91 deletions
+276
-91
Makefile
Makefile
+1
-0
interface.c
interface.c
+98
-14
interface.h
interface.h
+10
-0
loop.c
loop.c
+2
-0
mtproto-client.c
mtproto-client.c
+32
-31
mtproto-common.c
mtproto-common.c
+5
-4
mtproto-common.h
mtproto-common.h
+2
-3
net.c
net.c
+14
-13
queries.c
queries.c
+28
-25
structures.c
structures.c
+64
-0
structures.h
structures.h
+6
-0
telegram.h
telegram.h
+1
-0
tree.h
tree.h
+13
-1
No files found.
Makefile
View file @
bf291df3
...
...
@@ -6,6 +6,7 @@ LD=cc
SRC
=
main.c loop.c interface.c net.c mtproto-common.c mtproto-client.c queries.c structures.c
OBJ
=
$
(
SRC:.c
=
.o
)
EXE
=
telegram
HDRS
=
include.h interface.h loop.h mtproto-client.h mtproto-common.h net.h queries.h structures.h telegram.h tree.h
all
:
$(SRC) $(EXE)
...
...
interface.c
View file @
bf291df3
...
...
@@ -9,6 +9,10 @@
#include <string.h>
#include "include.h"
#include "queries.h"
#include "interface.h"
#include "telegram.h"
#include "structures.h"
char
*
default_prompt
=
">"
;
char
*
get_default_prompt
(
void
)
{
...
...
@@ -23,16 +27,18 @@ char *commands[] = {
"help"
,
"msg"
,
"contact_list"
,
"stats"
,
0
};
int
commands_flags
[]
=
{
070
,
072
,
00
,
07
,
07
,
};
char
*
a
=
0
;
char
*
*
user_list
=
&
a
;
char
*
user_list
[
MAX_USER_NUM
+
1
]
;
char
**
chat_list
=
&
a
;
int
init_token
(
char
**
q
)
{
...
...
@@ -91,12 +97,27 @@ int get_complete_mode (void) {
int
s
=
0
;
while
(
1
)
{
get_token
(
&
q
,
&
l
);
if
(
!*
q
)
{
return
flags
&
7
;
}
if
(
!*
q
)
{
return
flags
?
flags
&
7
:
7
;
}
s
++
;
if
(
s
<=
4
)
{
flags
>>=
3
;
}
}
}
extern
int
user_num
;
extern
struct
user
*
Users
[];
int
complete_user_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
while
(
index
<
user_num
&&
(
!
Users
[
index
]
->
print_name
||
strncmp
(
Users
[
index
]
->
print_name
,
text
,
len
)))
{
index
++
;
}
if
(
index
<
user_num
)
{
*
R
=
strdup
(
Users
[
index
]
->
print_name
);
return
index
;
}
else
{
return
-
1
;
}
}
int
complete_string_list
(
char
**
list
,
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
while
(
list
[
index
]
&&
strncmp
(
list
[
index
],
text
,
len
))
{
...
...
@@ -137,7 +158,7 @@ char *command_generator (const char *text, int state) {
index
=
complete_string_list
(
commands
,
index
,
text
,
len
,
&
R
);
return
R
;
case
1
:
index
=
complete_
string_list
(
user_list
,
index
,
text
,
len
,
&
R
);
index
=
complete_
user_list
(
index
,
text
,
len
,
&
R
);
return
R
;
case
2
:
index
=
complete_string_list
(
chat_list
,
index
,
text
,
len
,
&
R
);
...
...
@@ -154,27 +175,90 @@ char **complete_text (char *text, int start UU, int end UU) {
}
void
interpreter
(
char
*
line
UU
)
{
if
(
line
&&
*
line
)
{
add_history
(
line
);
}
if
(
!
memcmp
(
line
,
"contact_list"
,
12
))
{
do_update_contact_list
();
}
else
if
(
!
memcmp
(
line
,
"stats"
,
5
))
{
static
char
stat_buf
[
1
<<
15
];
print_stat
(
stat_buf
,
(
1
<<
15
)
-
1
);
printf
(
"%s
\n
"
,
stat_buf
);
}
}
int
readline_active
;
void
rprintf
(
const
char
*
format
,
...)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
int
saved_point
=
rl_point
;
char
*
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stdout
,
format
,
ap
);
va_end
(
ap
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
void
hexdump
(
int
*
in_ptr
,
int
*
in_end
)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
int
*
ptr
=
in_ptr
;
while
(
ptr
<
in_end
)
{
fprintf
(
stdout
,
" %08x"
,
*
(
ptr
++
));
}
fprintf
(
stdout
,
"
\n
"
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
void
logprintf
(
const
char
*
format
,
...)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
printf
(
COLOR_GREY
" *** "
);
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stdout
,
format
,
ap
);
va_end
(
ap
);
printf
(
COLOR_NORMAL
);
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
interface.h
View file @
bf291df3
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#define COLOR_RED "\033[31;1m"
#define COLOR_NORMAL "\033[0m"
#define COLOR_GREEN "\033[32;1m"
#define COLOR_GREY "\033[37;1m"
char
*
get_default_prompt
(
void
);
char
*
complete_none
(
const
char
*
text
,
int
state
);
char
**
complete_text
(
char
*
text
,
int
start
,
int
end
);
void
interpreter
(
char
*
line
);
void
rprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
iprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
logprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
hexdump
(
int
*
in_ptr
,
int
*
in_end
);
#endif
loop.c
View file @
bf291df3
...
...
@@ -167,6 +167,7 @@ void read_auth_file (void) {
close
(
auth_file_fd
);
}
int
readline_active
;
int
loop
(
void
)
{
on_start
();
read_auth_file
();
...
...
@@ -216,6 +217,7 @@ int loop (void) {
fflush
(
stdout
);
fflush
(
stderr
);
readline_active
=
1
;
rl_callback_handler_install
(
get_default_prompt
(),
interpreter
);
rl_attempted_completion_function
=
(
CPPFunction
*
)
complete_text
;
rl_completion_entry_function
=
complete_none
;
...
...
mtproto-client.c
View file @
bf291df3
...
...
@@ -22,6 +22,7 @@
#include "include.h"
#include "queries.h"
#include "loop.h"
#include "interface.h"
#define sha1 SHA1
...
...
@@ -89,13 +90,13 @@ static int rsa_load_public_key (const char *public_key_name) {
pubKey
=
NULL
;
FILE
*
f
=
fopen
(
public_key_name
,
"r"
);
if
(
f
==
NULL
)
{
fprintf
(
stderr
,
"Couldn't open public key file: %s
\n
"
,
public_key_name
);
logprintf
(
"Couldn't open public key file: %s
\n
"
,
public_key_name
);
return
-
1
;
}
pubKey
=
PEM_read_RSAPublicKey
(
f
,
NULL
,
NULL
,
NULL
);
fclose
(
f
);
if
(
pubKey
==
NULL
)
{
fprintf
(
stderr
,
"PEM_read_RSAPublicKey returns NULL.
\n
"
);
logprintf
(
"PEM_read_RSAPublicKey returns NULL.
\n
"
);
return
-
1
;
}
...
...
@@ -205,7 +206,7 @@ unsigned p1, p2;
int
process_respq_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
int
i
;
if
(
verbosity
)
{
fprintf
(
stderr
,
"process_respq_answer(), len=%d
\n
"
,
len
);
logprintf
(
"process_respq_answer(), len=%d
\n
"
,
len
);
}
assert
(
len
>=
76
);
assert
(
!*
(
long
long
*
)
packet
);
...
...
@@ -227,7 +228,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
p1
=
0
,
p2
=
0
;
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"%lld received
\n
"
,
what
);
logprintf
(
"%lld received
\n
"
,
what
);
}
int
it
=
0
;
...
...
@@ -275,7 +276,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
if
(
verbosity
)
{
fprintf
(
stderr
,
"p1 = %d, p2 = %d, %d iterations
\n
"
,
p1
,
p2
,
it
);
logprintf
(
"p1 = %d, p2 = %d, %d iterations
\n
"
,
p1
,
p2
,
it
);
}
/// ++p1; ///
...
...
@@ -286,12 +287,12 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
long
long
*
fingerprints
=
(
long
long
*
)
(
from
+
8
);
for
(
i
=
0
;
i
<
fingerprints_num
;
i
++
)
{
if
(
fingerprints
[
i
]
==
pk_fingerprint
)
{
//
fprintf (stderr,
"found our public key at position %d\n", i);
//
logprintf (
"found our public key at position %d\n", i);
break
;
}
}
if
(
i
==
fingerprints_num
)
{
fprintf
(
stderr
,
"fatal: don't have any matching keys (%016llx expected)
\n
"
,
pk_fingerprint
);
logprintf
(
"fatal: don't have any matching keys (%016llx expected)
\n
"
,
pk_fingerprint
);
exit
(
2
);
}
// create inner part (P_Q_inner_data)
...
...
@@ -378,10 +379,10 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
int
process_dh_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"process_dh_answer(), len=%d
\n
"
,
len
);
logprintf
(
"process_dh_answer(), len=%d
\n
"
,
len
);
}
if
(
len
<
116
)
{
fprintf
(
stderr
,
"%u * %u = %llu"
,
p1
,
p2
,
what
);
logprintf
(
"%u * %u = %llu"
,
p1
,
p2
,
what
);
}
assert
(
len
>=
116
);
assert
(
!*
(
long
long
*
)
packet
);
...
...
@@ -418,7 +419,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
GET_DC
(
c
)
->
server_time_delta
=
server_time
-
time
(
0
);
GET_DC
(
c
)
->
server_time_udelta
=
server_time
-
get_utime
(
CLOCK_MONOTONIC
);
//
fprintf (stderr,
"server time is %d, delta = %d\n", server_time, server_time_delta);
//
logprintf (
"server time is %d, delta = %d\n", server_time, server_time_delta);
// Build set_client_DH_params answer
clear_packet
();
...
...
@@ -474,7 +475,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
int
process_auth_complete
(
struct
connection
*
c
UU
,
char
*
packet
,
int
len
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"process_dh_answer(), len=%d
\n
"
,
len
);
logprintf
(
"process_dh_answer(), len=%d
\n
"
,
len
);
}
assert
(
len
==
72
);
assert
(
!*
(
long
long
*
)
packet
);
...
...
@@ -493,7 +494,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
assert
(
!
memcmp
(
packet
+
56
,
sha1_buffer
+
4
,
16
));
GET_DC
(
c
)
->
server_salt
=
*
(
long
long
*
)
server_nonce
^
*
(
long
long
*
)
new_nonce
;
if
(
verbosity
>=
3
)
{
fprintf
(
stderr
,
"auth_key_id=%016llx
\n
"
,
GET_DC
(
c
)
->
auth_key_id
);
logprintf
(
"auth_key_id=%016llx
\n
"
,
GET_DC
(
c
)
->
auth_key_id
);
}
//kprintf ("OK\n");
...
...
@@ -503,7 +504,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
c_state
=
st_authorized
;
//return 1;
if
(
verbosity
)
{
fprintf
(
stderr
,
"Auth success
\n
"
);
logprintf
(
"Auth success
\n
"
);
}
auth_success
++
;
GET_DC
(
c
)
->
flags
|=
1
;
...
...
@@ -568,7 +569,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
sha1
((
unsigned
char
*
)
&
enc
->
server_salt
,
enc_len
,
sha1_buffer
);
//printf ("enc_len is %d\n", enc_len);
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"sending message with sha1 %08x
\n
"
,
*
(
int
*
)
sha1_buffer
);
logprintf
(
"sending message with sha1 %08x
\n
"
,
*
(
int
*
)
sha1_buffer
);
}
memcpy
(
enc
->
msg_key
,
sha1_buffer
+
4
,
16
);
init_aes_auth
(
DC
->
auth_key
,
enc
->
msg_key
,
AES_ENCRYPT
);
...
...
@@ -612,7 +613,7 @@ int auth_work_start (struct connection *c UU) {
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
);
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"work_container: msg_id = %lld
\n
"
,
msg_id
);
logprintf
(
"work_container: msg_id = %lld
\n
"
,
msg_id
);
}
assert
(
fetch_int
()
==
CODE_msg_container
);
int
n
=
fetch_int
();
...
...
@@ -632,7 +633,7 @@ void work_container (struct connection *c, long long msg_id UU) {
void
work_new_session_created
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"work_new_session_created: msg_id = %lld
\n
"
,
msg_id
);
logprintf
(
"work_new_session_created: msg_id = %lld
\n
"
,
msg_id
);
}
assert
(
fetch_int
()
==
(
int
)
CODE_new_session_created
);
fetch_long
();
// first message id
...
...
@@ -643,7 +644,7 @@ void work_new_session_created (struct connection *c, long long msg_id UU) {
void
work_msgs_ack
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"work_msgs_ack: msg_id = %lld
\n
"
,
msg_id
);
logprintf
(
"work_msgs_ack: msg_id = %lld
\n
"
,
msg_id
);
}
assert
(
fetch_int
()
==
CODE_msgs_ack
);
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -657,7 +658,7 @@ void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
void
work_rpc_result
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"work_rpc_result: msg_id = %lld
\n
"
,
msg_id
);
logprintf
(
"work_rpc_result: msg_id = %lld
\n
"
,
msg_id
);
}
assert
(
fetch_int
()
==
(
int
)
CODE_rpc_result
);
long
long
id
=
fetch_long
();
...
...
@@ -685,7 +686,7 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
work_rpc_result
(
c
,
msg_id
);
return
;
}
fprintf
(
stderr
,
"Unknown message:
\n
"
);
logprintf
(
"Unknown message:
\n
"
);
hexdump_in
();
}
...
...
@@ -693,7 +694,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
const
int
MINSZ
=
offsetof
(
struct
encrypted_message
,
message
);
const
int
UNENCSZ
=
offsetof
(
struct
encrypted_message
,
server_salt
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"process_rpc_message(), len=%d
\n
"
,
len
);
logprintf
(
"process_rpc_message(), len=%d
\n
"
,
len
);
}
assert
(
len
>=
MINSZ
&&
(
len
&
15
)
==
(
UNENCSZ
&
15
));
struct
dc
*
DC
=
GET_DC
(
c
);
...
...
@@ -717,7 +718,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
assert
(
this_server_time
>=
st
-
300
&&
this_server_time
<=
st
+
30
);
//assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1);
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"received mesage id %016llx
\n
"
,
enc
->
msg_id
);
logprintf
(
"received mesage id %016llx
\n
"
,
enc
->
msg_id
);
}
server_last_msg_id
=
enc
->
msg_id
;
...
...
@@ -727,7 +728,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
assert
(
l
>=
(
MINSZ
-
UNENCSZ
)
+
8
);
//assert (enc->message[0] == CODE_rpc_result && *(long long *)(enc->message + 1) == client_last_msg_id);
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"OK, message is good!
\n
"
);
logprintf
(
"OK, message is good!
\n
"
);
}
++
good_messages
;
...
...
@@ -745,11 +746,11 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"outbound rpc connection #%d : received rpc answer %d with %d content bytes
\n
"
,
c
->
fd
,
op
,
len
);
logprintf
(
"outbound rpc connection #%d : received rpc answer %d with %d content bytes
\n
"
,
c
->
fd
,
op
,
len
);
}
if
(
len
>=
MAX_RESPONSE_SIZE
/* - 12*/
||
len
<
0
/*12*/
)
{
fprintf
(
stderr
,
"answer too long (%d bytes), skipping
\n
"
,
len
);
logprintf
(
"answer too long (%d bytes), skipping
\n
"
,
len
);
return
0
;
}
...
...
@@ -758,7 +759,7 @@ int rpc_execute (struct connection *c, int op, int len) {
assert
(
read_in
(
c
,
Response
,
Response_len
)
==
Response_len
);
Response
[
Response_len
]
=
0
;
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"have %d Response bytes
\n
"
,
Response_len
);
logprintf
(
"have %d Response bytes
\n
"
,
Response_len
);
}
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
...
...
@@ -782,7 +783,7 @@ int rpc_execute (struct connection *c, int op, int len) {
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
return
0
;
default:
fprintf
(
stderr
,
"fatal: cannot receive answer in state %d
\n
"
,
c_state
);
logprintf
(
"fatal: cannot receive answer in state %d
\n
"
,
c_state
);
exit
(
2
);
}
...
...
@@ -792,14 +793,14 @@ int rpc_execute (struct connection *c, int op, int len) {
int
tc_close
(
struct
connection
*
c
,
int
who
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"outbound http connection #%d : closing by %d
\n
"
,
c
->
fd
,
who
);
logprintf
(
"outbound http connection #%d : closing by %d
\n
"
,
c
->
fd
,
who
);
}
return
0
;
}
int
tc_becomes_ready
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"outbound connection #%d becomes ready
\n
"
,
c
->
fd
);
logprintf
(
"outbound connection #%d becomes ready
\n
"
,
c
->
fd
);
}
char
byte
=
0xef
;
assert
(
write_out
(
c
,
&
byte
,
1
)
==
1
);
...
...
@@ -816,7 +817,7 @@ int tc_becomes_ready (struct connection *c) {
auth_work_start
(
c
);
break
;
default:
fprintf
(
stderr
,
"c_state = %d
\n
"
,
c_state
);
logprintf
(
"c_state = %d
\n
"
,
c_state
);
assert
(
0
);
}
return
0
;
...
...
@@ -842,7 +843,7 @@ void on_start (void) {
exit
(
1
);
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"public key '%s' loaded successfully
\n
"
,
rsa_public_key_name
);
logprintf
(
"public key '%s' loaded successfully
\n
"
,
rsa_public_key_name
);
}
pk_fingerprint
=
compute_rsa_key_fingerprint
(
pubKey
);
}
...
...
@@ -858,7 +859,7 @@ void dc_authorize (struct dc *DC) {
dc_create_session
(
DC
);
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Starting authorization for DC #%d: %s:%d
\n
"
,
DC
->
id
,
DC
->
ip
,
DC
->
port
);
logprintf
(
"Starting authorization for DC #%d: %s:%d
\n
"
,
DC
->
id
,
DC
->
ip
,
DC
->
port
);
}
net_loop
(
0
,
auth_ok
);
}
mtproto-common.c
View file @
bf291df3
...
...
@@ -16,6 +16,7 @@
#include <openssl/sha.h>
#include "mtproto-common.h"
#include "interface.h"
long
long
rsa_encrypted_chunks
,
rsa_decrypted_chunks
;
...
...
@@ -28,7 +29,7 @@ int get_random_bytes (void *buf, int n) {
r
=
read
(
h
,
buf
,
n
);
if
(
r
>
0
)
{
if
(
verbosity
>=
3
)
{
fprintf
(
stderr
,
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
logprintf
(
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
}
}
close
(
h
);
...
...
@@ -71,14 +72,14 @@ void prng_seed (const char *password_filename, int password_length) {
if
(
password_filename
)
{
int
fd
=
open
(
password_filename
,
O_RDONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
logprintf
(
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
int
l
=
read
(
fd
,
a
+
s
,
password_length
);
if
(
l
<
0
)
{
fprintf
(
stderr
,
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
logprintf
(
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
if
(
verbosity
>
0
)
{
fprintf
(
stderr
,
"read %d bytes from password file.
\n
"
,
l
);
logprintf
(
"read %d bytes from password file.
\n
"
,
l
);
}
s
+=
l
;
}
...
...
mtproto-common.h
View file @
bf291df3
...
...
@@ -7,6 +7,7 @@
#include <openssl/aes.h>
#include <stdio.h>
#include "interface.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
...
...
@@ -409,8 +410,6 @@ int pad_aes_encrypt (char *from, int from_len, char *to, int size);
int
pad_aes_decrypt
(
char
*
from
,
int
from_len
,
char
*
to
,
int
size
);
static
inline
void
hexdump_in
(
void
)
{
int
*
ptr
=
in_ptr
;
while
(
ptr
<
in_end
)
{
fprintf
(
stderr
,
" %08x"
,
*
(
ptr
++
));
}
fprintf
(
stderr
,
"
\n
"
);
hexdump
(
in_ptr
,
in_end
);
}
#endif
net.c
View file @
bf291df3
...
...
@@ -17,6 +17,7 @@
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "tree.h"
#include "interface.h"
DEFINE_TREE
(
int
,
int
,
int_cmp
,
0
)
...
...
@@ -156,7 +157,7 @@ struct connection *create_connection (const char *host, int port, struct session
if
(
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
if
(
errno
!=
EINPROGRESS
)
{
fprintf
(
stderr
,
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
logprintf
(
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
close
(
fd
);
free
(
c
);
return
0
;
...
...
@@ -183,7 +184,7 @@ struct connection *create_connection (const char *host, int port, struct session
assert
(
!
Connections
[
fd
]);
Connections
[
fd
]
=
c
;
if
(
verbosity
)
{
fprintf
(
stderr
,
"connect to %s:%d successful
\n
"
,
host
,
port
);
logprintf
(
"connect to %s:%d successful
\n
"
,
host
,
port
);
}
if
(
c
->
methods
->
ready
)
{
c
->
methods
->
ready
(
c
);
...
...
@@ -211,7 +212,7 @@ void fail_connection (struct connection *c) {
void
try_write
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"try write: fd = %d
\n
"
,
c
->
fd
);
logprintf
(
"try write: fd = %d
\n
"
,
c
->
fd
);
}
int
x
=
0
;
while
(
c
->
out_head
)
{
...
...
@@ -238,12 +239,12 @@ void try_write (struct connection *c) {
}
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
logprintf
(
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
}
c
->
out_bytes
-=
x
;
}
void
hexdump
(
struct
connection_buffer
*
b
)
{
void
hexdump
_buf
(
struct
connection_buffer
*
b
)
{
int
pos
=
0
;
int
rem
=
8
;
while
(
b
)
{
...
...
@@ -270,7 +271,7 @@ void hexdump (struct connection_buffer *b) {
void
try_rpc_read
(
struct
connection
*
c
)
{
assert
(
c
->
in_head
);
if
(
verbosity
>=
4
)
{
hexdump
(
c
->
in_head
);
hexdump
_buf
(
c
->
in_head
);
}
while
(
1
)
{
...
...
@@ -307,7 +308,7 @@ void try_rpc_read (struct connection *c) {
void
try_read
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"try read: fd = %d
\n
"
,
c
->
fd
);
logprintf
(
"try read: fd = %d
\n
"
,
c
->
fd
);
}
if
(
!
c
->
in_tail
)
{
c
->
in_head
=
c
->
in_tail
=
new_connection_buffer
(
1
<<
20
);
...
...
@@ -334,7 +335,7 @@ void try_read (struct connection *c) {
}
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
logprintf
(
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
}
c
->
in_bytes
+=
x
;
if
(
x
)
{
...
...
@@ -356,15 +357,15 @@ int connections_make_poll_array (struct pollfd *fds, int max) {
fds
++
;
max
--
;
}
if
(
verbosity
>=
3
)
{
fprintf
(
stderr
,
"%d connections in poll
\n
"
,
_max
-
max
);
if
(
verbosity
>=
10
)
{
logprintf
(
"%d connections in poll
\n
"
,
_max
-
max
);
}
return
_max
-
max
;
}
void
connections_poll_result
(
struct
pollfd
*
fds
,
int
max
)
{
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"connections_poll_result: max = %d
\n
"
,
max
);
if
(
verbosity
>=
10
)
{
logprintf
(
"connections_poll_result: max = %d
\n
"
,
max
);
}
int
i
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
...
...
@@ -374,7 +375,7 @@ void connections_poll_result (struct pollfd *fds, int max) {
}
if
(
fds
[
i
].
revents
&
(
POLLHUP
|
POLLERR
|
POLLRDHUP
))
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"fail connection
\n
"
);
logprintf
(
"fail connection
\n
"
);
}
fail_connection
(
c
);
}
else
if
(
fds
[
i
].
revents
&
POLLOUT
)
{
...
...
queries.c
View file @
bf291df3
...
...
@@ -43,7 +43,7 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
dc_create_session
(
DC
);
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
logprintf
(
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
}
struct
query
*
q
=
malloc
(
sizeof
(
*
q
));
q
->
data_len
=
ints
;
...
...
@@ -51,11 +51,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
memcpy
(
q
->
data
,
data
,
4
*
ints
);
q
->
msg_id
=
encrypt_send_message
(
DC
->
sessions
[
0
]
->
c
,
data
,
ints
,
1
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"Msg_id is %lld
\n
"
,
q
->
msg_id
);
logprintf
(
"Msg_id is %lld
\n
"
,
q
->
msg_id
);
}
q
->
methods
=
methods
;
if
(
queries_tree
)
{
fprintf
(
stderr
,
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
logprintf
(
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
}
queries_tree
=
tree_insert_query
(
queries_tree
,
q
,
lrand48
());
...
...
@@ -77,12 +77,12 @@ void query_error (long long id) {
int
error_len
=
prefetch_strlen
();
char
*
error
=
fetch_str
(
error_len
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
logprintf
(
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
}
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"No such query
\n
"
);
logprintf
(
"No such query
\n
"
);
}
}
else
{
remove_event_timer
(
&
q
->
ev
);
...
...
@@ -100,10 +100,10 @@ static int packed_buffer[MAX_PACKED_SIZE / 4];
void
query_result
(
long
long
id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"result for query #%lld
\n
"
,
id
);
logprintf
(
"result for query #%lld
\n
"
,
id
);
}
if
(
verbosity
>=
4
)
{
fprintf
(
stderr
,
"result: "
);
logprintf
(
"result: "
);
hexdump_in
();
}
int
op
=
prefetch_int
();
...
...
@@ -124,8 +124,8 @@ void query_result (long long id UU) {
int
err
=
inflate
(
&
strm
,
Z_FINISH
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"inflate error = %d
\n
"
,
err
);
fprintf
(
stderr
,
"inflated %d bytes
\n
"
,
(
int
)
strm
.
total_out
);
logprintf
(
"inflate error = %d
\n
"
,
err
);
logprintf
(
"inflated %d bytes
\n
"
,
(
int
)
strm
.
total_out
);
}
end
=
in_ptr
;
eend
=
in_end
;
...
...
@@ -133,14 +133,14 @@ void query_result (long long id UU) {
in_ptr
=
packed_buffer
;
in_end
=
in_ptr
+
strm
.
total_out
/
4
;
if
(
verbosity
>=
4
)
{
fprintf
(
stderr
,
"Unzipped data: "
);
logprintf
(
"Unzipped data: "
);
hexdump_in
();
}
}
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"No such query
\n
"
);
logprintf
(
"No such query
\n
"
);
}
}
else
{
remove_event_timer
(
&
q
->
ev
);
...
...
@@ -162,16 +162,18 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
struct
tree_timer
*
timer_tree
;
void
insert_event_timer
(
struct
event_timer
*
ev
)
{
return
;
fprintf
(
stderr
,
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
if
(
verbosity
>
2
)
{
logprintf
(
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
tree_check_timer
(
timer_tree
);
timer_tree
=
tree_insert_timer
(
timer_tree
,
ev
,
lrand48
());
tree_check_timer
(
timer_tree
);
}
void
remove_event_timer
(
struct
event_timer
*
ev
)
{
return
;
fprintf
(
stderr
,
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
if
(
verbosity
>
2
)
{
logprintf
(
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
tree_check_timer
(
timer_tree
);
timer_tree
=
tree_delete_timer
(
timer_tree
,
ev
);
tree_check_timer
(
timer_tree
);
...
...
@@ -207,7 +209,7 @@ int help_get_config_on_answer (struct query *q UU) {
assert
(
test_mode
==
CODE_bool_false
);
int
this_dc
=
fetch_int
();
if
(
verbosity
)
{
fprintf
(
stderr
,
"this_dc = %d
\n
"
,
this_dc
);
logprintf
(
"this_dc = %d
\n
"
,
this_dc
);
}
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
...
...
@@ -222,7 +224,7 @@ int help_get_config_on_answer (struct query *q UU) {
char
*
ip
=
fetch_str
(
l2
);
int
port
=
fetch_int
();
if
(
verbosity
)
{
fprintf
(
stderr
,
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
logprintf
(
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
}
if
(
!
DC_list
[
id
])
{
alloc_dc
(
id
,
strndup
(
ip
,
l2
),
port
);
...
...
@@ -230,7 +232,7 @@ int help_get_config_on_answer (struct query *q UU) {
}
max_chat_size
=
fetch_int
();
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"chat_size = %d
\n
"
,
max_chat_size
);
logprintf
(
"chat_size = %d
\n
"
,
max_chat_size
);
}
return
0
;
}
...
...
@@ -259,7 +261,7 @@ int send_code_on_error (struct query *q UU, int error_code, int l, char *error)
int
i
=
error
[
s
]
-
'0'
;
want_dc_num
=
i
;
}
else
{
fprintf
(
stderr
,
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
}
return
0
;
...
...
@@ -343,13 +345,13 @@ int sign_in_on_answer (struct query *q UU) {
fetch_user
(
&
User
);
sign_in_ok
=
1
;
if
(
verbosity
)
{
fprintf
(
stderr
,
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
logprintf
(
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
}
return
0
;
}
int
sign_in_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
fprintf
(
stderr
,
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
sign_in_ok
=
-
1
;
return
0
;
}
...
...
@@ -371,11 +373,13 @@ int do_send_code_result (const char *code) {
return
sign_in_ok
;
}
extern
char
*
user_list
[];
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
int
i
;
assert
(
fetch_int
()
==
(
int
)
CODE_contacts_contacts
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_contact
);
fetch_int
();
// id
...
...
@@ -384,9 +388,8 @@ int get_contacts_on_answer (struct query *q UU) {
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
struct
user
User
;
fetch_user
(
&
User
);
rprintf
(
"User: id = %d, first_name = %s, last_name = %s
\n
"
,
User
.
id
,
User
.
first_name
,
User
.
last_name
);
struct
user
*
U
=
fetch_alloc_user
();
rprintf
(
"User #%d: "
COLOR_RED
"%s %s"
COLOR_NORMAL
" ("
COLOR_GREEN
"%s"
COLOR_NORMAL
")
\n
"
,
U
->
id
,
U
->
first_name
,
U
->
last_name
,
U
->
print_name
);
}
return
0
;
}
...
...
structures.c
View file @
bf291df3
#include <assert.h>
#include "structures.h"
#include "mtproto-common.h"
#include "telegram.h"
#include "tree.h"
void
fetch_file_location
(
struct
file_location
*
loc
)
{
int
x
=
fetch_int
();
...
...
@@ -48,6 +50,25 @@ void fetch_user (struct user *U) {
}
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
;
while
(
*
s
)
{
if
(
*
s
==
' '
)
{
*
s
=
'_'
;
}
s
++
;
}
if
(
x
==
CODE_user_deleted
)
{
U
->
flags
=
2
;
return
;
...
...
@@ -79,3 +100,46 @@ void fetch_user (struct user *U) {
U
->
flags
|=
16
;
}
}
#define user_cmp(a,b) ((a)->id - (b)->id)
DEFINE_TREE
(
user
,
struct
user
*
,
user_cmp
,
0
)
struct
tree_user
*
user_tree
;
int
user_num
;
struct
user
*
Users
[
MAX_USER_NUM
];
int
users_allocated
;
struct
user
*
fetch_alloc_user
(
void
)
{
struct
user
*
U
=
malloc
(
sizeof
(
*
U
));
fetch_user
(
U
);
users_allocated
++
;
struct
user
*
U1
=
tree_lookup_user
(
user_tree
,
U
);
if
(
U1
)
{
free_user
(
U1
);
memcpy
(
U1
,
U
,
sizeof
(
*
U
));
free
(
U
);
users_allocated
--
;
return
U1
;
}
else
{
user_tree
=
tree_insert_user
(
user_tree
,
U
,
lrand48
());
Users
[
user_num
++
]
=
U
;
return
U
;
}
}
void
free_user
(
struct
user
*
U
)
{
if
(
U
->
first_name
)
{
free
(
U
->
first_name
);
}
if
(
U
->
last_name
)
{
free
(
U
->
last_name
);
}
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
if
(
U
->
phone
)
{
free
(
U
->
phone
);
}
}
int
print_stat
(
char
*
s
,
int
len
)
{
return
snprintf
(
s
,
len
,
"user_num
\t
%d
\n
"
"users_allocated
\t
%d
\n
"
,
user_num
,
users_allocated
);
}
structures.h
View file @
bf291df3
...
...
@@ -20,6 +20,7 @@ struct user {
char
*
first_name
;
char
*
last_name
;
char
*
phone
;
char
*
print_name
;
long
long
access_hash
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
...
...
@@ -28,4 +29,9 @@ struct user {
void
fetch_file_location
(
struct
file_location
*
loc
);
void
fetch_user
(
struct
user
*
U
);
struct
user
*
fetch_alloc_user
(
void
);
void
free_user
(
struct
user
*
U
);
int
print_stat
(
char
*
s
,
int
len
);
#endif
telegram.h
View file @
bf291df3
#define MAX_DC_NUM 9
#define MAX_USER_NUM 1000
tree.h
View file @
bf291df3
...
...
@@ -51,7 +51,12 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
} else {\
int c = X_CMP (x, T->x);\
assert (c);\
return tree_insert_ ## X_NAME (c < 0 ? T->left : T->right, x, y);\
if (c < 0) { \
T->left = tree_insert_ ## X_NAME (T->left, x, y);\
} else { \
T->right = tree_insert_ ## X_NAME (T->right, x, y);\
} \
return T; \
}\
}\
}\
...
...
@@ -96,6 +101,13 @@ X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
return T ? T->x : X_UNSET;\
}\
\
void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\
if (!T) { return; } \
tree_act_ ## X_NAME (T->left, act); \
act (T->x); \
tree_act_ ## X_NAME (T->right, act); \
}\
\
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\
return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \
...
...
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