Implement login and authentication mechanism and fix the logging mechanism
Use purple debugging functions by formatting the string beforehand and then passing the readily formatted string, instead of doing it with va_list. Log into the telegram network using the provided SMS code and hash or request a new one, in case one of those isn't provided. Store and load the state using the file config/auth, to be able to restore previous logins.
This commit is contained in:
parent
90f7b39e11
commit
62090b3ca0
8 changed files with 280 additions and 155 deletions
139
loop.c
139
loop.c
|
@ -75,6 +75,7 @@ extern int queries_num;
|
|||
int unread_messages;
|
||||
void got_it (char *line, int len);
|
||||
void net_loop (int flags, int (*is_end)(void)) {
|
||||
logprintf("starting net_loop()\n");
|
||||
while (!is_end ()) {
|
||||
struct pollfd fds[101];
|
||||
int cc = 0;
|
||||
|
@ -84,11 +85,13 @@ void net_loop (int flags, int (*is_end)(void)) {
|
|||
cc ++;
|
||||
}
|
||||
|
||||
logprintf("writing_state_file()\n");
|
||||
write_state_file ();
|
||||
int x = connections_make_poll_array (fds + cc, 101 - cc) + cc;
|
||||
double timer = next_timer_in ();
|
||||
if (timer > 1000) { timer = 1000; }
|
||||
if (poll (fds, x, timer) < 0) {
|
||||
logprintf("poll returned -1, wait a little bit.\n");
|
||||
work_timers ();
|
||||
continue;
|
||||
}
|
||||
|
@ -109,7 +112,7 @@ void net_loop (int flags, int (*is_end)(void)) {
|
|||
lua_do_all ();
|
||||
#endif
|
||||
if (safe_quit && !queries_num) {
|
||||
printf ("All done. Exit\n");
|
||||
logprintf ("All done. Exit\n");
|
||||
rl_callback_handler_remove ();
|
||||
exit (0);
|
||||
}
|
||||
|
@ -182,6 +185,11 @@ void write_dc (int auth_file_fd, struct dc *DC) {
|
|||
}
|
||||
|
||||
int our_id;
|
||||
|
||||
void store_config () {
|
||||
write_auth_file();
|
||||
}
|
||||
|
||||
void write_auth_file (void) {
|
||||
if (binlog_enabled) { return; }
|
||||
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
|
||||
|
@ -220,9 +228,9 @@ void read_dc (int auth_file_fd, int id, unsigned ver) {
|
|||
assert (read (auth_file_fd, &DC->auth_key_id, 8) == 8);
|
||||
assert (read (auth_file_fd, &DC->auth_key, 256) == 256);
|
||||
assert (read (auth_file_fd, &DC->server_salt, 8) == 8);
|
||||
printf("auth_key_id: %lli \n", DC->auth_key_id);
|
||||
printf("auth_key_id: ?");
|
||||
printf("server_salt: %lli \n", DC->server_salt);
|
||||
logprintf("auth_key_id: %lli \n", DC->auth_key_id);
|
||||
logprintf("auth_key_id: ?");
|
||||
logprintf("server_salt: %lli \n", DC->server_salt);
|
||||
if (DC->auth_key_id) {
|
||||
DC->flags |= 1;
|
||||
}
|
||||
|
@ -248,7 +256,10 @@ void read_auth_file (void) {
|
|||
empty_auth_file ();
|
||||
}
|
||||
assert (auth_file_fd >= 0);
|
||||
|
||||
// amount of data centers
|
||||
unsigned x;
|
||||
// magic number of file
|
||||
unsigned m;
|
||||
if (read (auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC && m != DC_SERIALIZED_MAGIC_V2)) {
|
||||
close (auth_file_fd);
|
||||
|
@ -463,7 +474,11 @@ int readline_active;
|
|||
int new_dc_num;
|
||||
int wait_dialog_list;
|
||||
|
||||
void init_loop (void) {
|
||||
/**
|
||||
* Discover the network and authorise with all data centers
|
||||
*/
|
||||
void network_connect (void) {
|
||||
verbosity = 0;
|
||||
on_start ();
|
||||
if (binlog_enabled) {
|
||||
double t = get_double_time ();
|
||||
|
@ -477,79 +492,141 @@ void init_loop (void) {
|
|||
} else {
|
||||
read_auth_file ();
|
||||
}
|
||||
printf("update prompt()\n");
|
||||
logprintf("update prompt()\n");
|
||||
update_prompt ();
|
||||
printf("update prompt() done... \n");
|
||||
logprintf("update prompt() done... \n");
|
||||
|
||||
assert (DC_list[dc_working_num]);
|
||||
if (!DC_working || !DC_working->auth_key_id) {
|
||||
// if (auth_state == 0) {
|
||||
logprintf("No working DC or not start_loopd.\n");
|
||||
DC_working = DC_list[dc_working_num];
|
||||
assert (!DC_working->auth_key_id);
|
||||
dc_authorize (DC_working);
|
||||
assert (DC_working->auth_key_id);
|
||||
auth_state = 100;
|
||||
write_auth_file ();
|
||||
logprintf("Authorized DataCentre: auth_key_id: %lld \n", DC_working->auth_key_id);
|
||||
}
|
||||
|
||||
if (verbosity) {
|
||||
logprintf ("Requesting info about DC...\n");
|
||||
}
|
||||
do_help_get_config ();
|
||||
printf("net_loop\n");
|
||||
logprintf("net_loop\n");
|
||||
net_loop (0, mcs);
|
||||
printf("net_loop done...\n");
|
||||
logprintf("net_loop done...\n");
|
||||
if (verbosity) {
|
||||
logprintf ("DC_info: %d new DC got\n", new_dc_num);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i <= MAX_DC_NUM; i++) if (DC_list[i] && !DC_list[i]->auth_key_id) {
|
||||
logprintf("DataCentre %d not start_loopd, authorizing...\n", i);
|
||||
dc_authorize (DC_list[i]);
|
||||
assert (DC_list[i]->auth_key_id);
|
||||
write_auth_file ();
|
||||
logprintf("DataCentre start_loopd, key id: %lld\n", DC_list[i]->auth_key_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the given phone is registered
|
||||
*/
|
||||
int network_phone_is_registered() {
|
||||
int res = do_auth_check_phone (default_username);
|
||||
assert(res >= 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return if the current client is registered.
|
||||
*/
|
||||
int network_client_is_registered() {
|
||||
return !(auth_state == 100 || !(DC_working->has_auth));
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a verification for the given client, by sending
|
||||
* a code to the current phone number
|
||||
*/
|
||||
char* network_request_registration ()
|
||||
{
|
||||
return do_send_code (default_username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the phone, by providing the code and the real name
|
||||
*
|
||||
* NOTE: This should be called when the phone number was previously
|
||||
* unknown to the telegram network.
|
||||
*/
|
||||
int network_verify_phone_registration(char* code, char *firstname, char *lastname)
|
||||
{
|
||||
if (do_send_code_result_auth (code, firstname, lastname) >= 0) {
|
||||
auth_state = 300;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the current client by providing the given code
|
||||
*/
|
||||
int network_verify_registration(const char *code, const char *sms_hash)
|
||||
{
|
||||
logprintf("telegram: pointer - code: %p, hash: %p\n", code, sms_hash);
|
||||
logprintf("telegram: string - code: %s, hash: %s\n", code, sms_hash);
|
||||
if (do_send_code_result (code, sms_hash) >= 0) {
|
||||
logprintf ("Authentication successfull, state = 300\n");
|
||||
auth_state = 300;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_loop (char* code, char* auth_mode) {
|
||||
printf("Calling start_loop()\n");
|
||||
printf("auth_state %i\n", auth_state);
|
||||
logprintf("Calling start_loop()\n");
|
||||
logprintf("auth_state %i\n", auth_state);
|
||||
if (auth_state == 100 || !(DC_working->has_auth)) {
|
||||
printf("auth_state == 100 || !(DC_working->has_auth)");
|
||||
logprintf("auth_state == 100 || !(DC_working->has_auth)");
|
||||
int res = do_auth_check_phone (default_username);
|
||||
assert (res >= 0);
|
||||
logprintf ("%s\n", res > 0 ? "phone registered" : "phone not registered");
|
||||
if (res > 0 && !register_mode) {
|
||||
// Register Mode 1
|
||||
printf ("Register Mode 1\n");
|
||||
logprintf ("Register Mode 1\n");
|
||||
if (code) {
|
||||
/*
|
||||
if (do_send_code_result (code) >= 0) {
|
||||
printf ("Authentication successfull, state = 300\n");
|
||||
logprintf ("Authentication successfull, state = 300\n");
|
||||
auth_state = 300;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
printf("No code given, attempting to register\n");
|
||||
logprintf("No code given, attempting to register\n");
|
||||
// Send Code
|
||||
printf ("auth mode %s\n", auth_mode);
|
||||
logprintf ("auth mode %s\n", auth_mode);
|
||||
/*
|
||||
if (strcmp(TELEGRAM_AUTH_MODE_SMS"sms", auth_mode)) {
|
||||
*/
|
||||
do_send_code (default_username);
|
||||
printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
|
||||
printf("storing current state in auth file...\n");
|
||||
logprintf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
|
||||
logprintf("storing current state in auth file...\n");
|
||||
write_auth_file ();
|
||||
printf("exitting...\n");
|
||||
logprintf("exitting...\n");
|
||||
return 0;
|
||||
/*
|
||||
} else {
|
||||
printf ("You typed \"call\", switching to phone system.\n");
|
||||
logprintf ("You typed \"call\", switching to phone system.\n");
|
||||
do_phone_call (default_username);
|
||||
printf ("Calling you!");
|
||||
logprintf ("Calling you!");
|
||||
}
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
printf ("User is not registered. Do you want to register? [Y/n] ");
|
||||
printf ("ERROR THIS IS NOT POSSIBLE!\n");
|
||||
logprintf ("User is not registered. Do you want to register? [Y/n] ");
|
||||
logprintf ("ERROR THIS IS NOT POSSIBLE!\n");
|
||||
return 1;
|
||||
// Register Mode 2
|
||||
// TODO: Requires first and last name, decide how to handle this.
|
||||
|
@ -559,13 +636,13 @@ int start_loop (char* code, char* auth_mode) {
|
|||
/*
|
||||
size_t size;
|
||||
char *first_name;
|
||||
printf ("First name: ");
|
||||
logprintf ("First name: ");
|
||||
if (net_getline (&first_name, &size) == -1) {
|
||||
perror ("getline()");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
char *last_name;
|
||||
printf ("Last name: ");
|
||||
logprintf ("Last name: ");
|
||||
if (net_getline (&last_name, &size) == -1) {
|
||||
perror ("getline()");
|
||||
exit (EXIT_FAILURE);
|
||||
|
@ -583,17 +660,17 @@ int start_loop (char* code, char* auth_mode) {
|
|||
} else {
|
||||
if (strcmp(TELEGRAM_AUTH_MODE_SMS, auth_mode)) {
|
||||
do_send_code (default_username);
|
||||
printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
|
||||
logprintf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
|
||||
} else {
|
||||
printf ("You typed \"call\", switching to phone system.\n");
|
||||
logprintf ("You typed \"call\", switching to phone system.\n");
|
||||
do_phone_call (default_username);
|
||||
printf ("Calling you! Code: ");
|
||||
logprintf ("Calling you! Code: ");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
printf("Authentication done\n");
|
||||
logprintf("Authentication done\n");
|
||||
|
||||
int i;
|
||||
for (i = 0; i <= MAX_DC_NUM; i++) if (DC_list[i] && !DC_list[i]->has_auth) {
|
||||
|
@ -636,12 +713,12 @@ int start_loop (char* code, char* auth_mode) {
|
|||
* with 0. In all other cases exit with 1.
|
||||
*/
|
||||
int loop_auto(char *username, char *code, char* auth_mode) {
|
||||
init_loop();
|
||||
network_connect();
|
||||
set_default_username (username);
|
||||
return start_loop(code, auth_mode);
|
||||
}
|
||||
|
||||
int loop (void) {
|
||||
init_loop();
|
||||
network_connect();
|
||||
return start_loop(NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -225,6 +225,7 @@ int rpc_send_packet (struct connection *c) {
|
|||
}
|
||||
|
||||
int rpc_send_message (struct connection *c, void *data, int len) {
|
||||
logprintf("rpc_send_message(...)\n");
|
||||
assert (len > 0 && !(len & 0xfc000003));
|
||||
int total_len = len >> 2;
|
||||
if (total_len < 0x7f) {
|
||||
|
@ -743,6 +744,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
|
|||
}
|
||||
|
||||
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful) {
|
||||
logprintf("encrypt_send_message(...)\n");
|
||||
struct dc *DC = GET_DC(c);
|
||||
struct session *S = c->session;
|
||||
assert (S);
|
||||
|
|
1
net.c
1
net.c
|
@ -634,6 +634,7 @@ struct dc *alloc_dc (int id, char *ip, int port UU) {
|
|||
}
|
||||
|
||||
void dc_create_session (struct dc *DC) {
|
||||
logprintf("dc_create_session(...)\n");
|
||||
struct session *S = talloc0 (sizeof (*S));
|
||||
assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0);
|
||||
S->dc = DC;
|
||||
|
|
|
@ -16,7 +16,7 @@ ifeq ($(ARCH),i686)
|
|||
else ifeq ($(ARCH),x86_64)
|
||||
ARCHFLAGS = -m64
|
||||
else
|
||||
ARCHFLAGS =
|
||||
ARCHFLAGS =
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
|
@ -83,4 +83,4 @@ clean:
|
|||
|
||||
.PHONY: run
|
||||
run: all install
|
||||
pidgin -d
|
||||
pidgin -d | grep telegram
|
||||
|
|
|
@ -59,12 +59,9 @@ static PurplePlugin *_telegram_protocol = NULL;
|
|||
*/
|
||||
void tg_cli_log_cb(const char* format, va_list ap)
|
||||
{
|
||||
// emulate libpurple logging function, because we cant pass va_list
|
||||
// directly
|
||||
time_t mtime = time(NULL);
|
||||
const char *mdate = purple_utf8_strftime("%H:%M:%S", localtime(&mtime));
|
||||
printf("(%s) prpl-telegram: ", mdate);
|
||||
vprintf(format, ap);
|
||||
char buffer[256];
|
||||
vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||
purple_debug_info(PLUGIN_ID, "%s", buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,73 +102,79 @@ static void tgprpl_tooltip_text(PurpleBuddy * buddy, PurpleNotifyUserInfo * info
|
|||
static void tgprpl_login(PurpleAccount * acct)
|
||||
{
|
||||
purple_debug_info(PLUGIN_ID, "tgprpl_login()\n");
|
||||
PurpleConnection *gc = purple_account_get_connection(acct);
|
||||
|
||||
const char *username = purple_account_get_username(acct);
|
||||
const char *code = purple_account_get_string(acct, "verification_key", NULL);
|
||||
const char *hostname = purple_account_get_string(acct, "server", TELEGRAM_TEST_SERVER);
|
||||
const char *verificationType = purple_account_get_string(acct, "verification_type", TELEGRAM_AUTH_MODE_SMS);
|
||||
int port = purple_account_get_int(acct, "port", TELEGRAM_DEFAULT_PORT);
|
||||
const char *username = purple_account_get_username(acct);
|
||||
const char *code = purple_account_get_string(acct, "verification_key", NULL);
|
||||
const char *hash = purple_account_get_string(acct, "verification_hash", NULL);
|
||||
const char *hostname = purple_account_get_string(acct, "server", TELEGRAM_TEST_SERVER);
|
||||
// const char *verificationType = purple_account_get_string(acct, "verification_type", TELEGRAM_AUTH_MODE_SMS);
|
||||
// int port = purple_account_get_int(acct, "port", TELEGRAM_DEFAULT_PORT);
|
||||
|
||||
printf("username: %s\n", username);
|
||||
printf("code: %s\n", code);
|
||||
printf("hostname: %s\n", hostname);
|
||||
purple_debug_info(PLUGIN_ID, "username: %s\n", username);
|
||||
purple_debug_info(PLUGIN_ID, "code: %s\n", code);
|
||||
purple_debug_info(PLUGIN_ID, "verification_hash: %s\n", hash);
|
||||
purple_debug_info(PLUGIN_ID, "hostname: %s\n", hostname);
|
||||
|
||||
// ensure config-file exists an
|
||||
purple_debug_info(PLUGIN_ID, "running_for_first_time()\n");
|
||||
running_for_first_time();
|
||||
|
||||
// load all settings: the known network topology, log and configuration file paths
|
||||
purple_debug_info(PLUGIN_ID, "parse_config()\n");
|
||||
parse_config ();
|
||||
purple_debug_info(PLUGIN_ID, "init_loop()\n");
|
||||
init_loop();
|
||||
purple_debug_info(PLUGIN_ID, "set_default_username()\n");
|
||||
set_default_username (username);
|
||||
purple_debug_info(PLUGIN_ID, "start_loop() -> Authentication\n");
|
||||
start_loop (code, verificationType);
|
||||
|
||||
|
||||
// TODO: Do proper input validation
|
||||
/*
|
||||
if (code && strcmp(code, "")) {
|
||||
code = NULL;
|
||||
}
|
||||
*/
|
||||
if (!code) {
|
||||
purple_notify_message(
|
||||
_telegram_protocol,
|
||||
PURPLE_NOTIFY_MSG_INFO,
|
||||
"Telegram Verification",
|
||||
"Telegram needs to verify this phone number. You should receive a SMS with a code soon, please copy that code into the account option 'Verification Key'.",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
// tg_login(username, code, TELEGRAM_AUTH_MODE_SMS);
|
||||
printf("Returned from tg_login...\n");
|
||||
|
||||
/*
|
||||
PurpleConnection *gc = purple_account_get_connection(acct);
|
||||
purple_debug_info(PLUGIN_ID, "logging in %s\n", username);
|
||||
// Connect to the network
|
||||
purple_debug_info(PLUGIN_ID, "Connecting to the Telegram network...\n");
|
||||
network_connect();
|
||||
|
||||
if (strcmp(sms_key[0], "")) {
|
||||
purple_debug_info(PLUGIN_ID, "no sms key -> send sms key request\n");
|
||||
}
|
||||
// Login
|
||||
if (!network_phone_is_registered()) {
|
||||
purple_debug_info(PLUGIN_ID, "Phone is not registered, registering...\n");
|
||||
}
|
||||
|
||||
purple_debug_info(PLUGIN_ID, "Connect\n");
|
||||
purple_connection_update_progress(gc, "Connecting", 0, 4);
|
||||
telegram_conn *conn;
|
||||
conn = g_new0(telegram_conn, 1);
|
||||
conn->gc = gc;
|
||||
if (!network_client_is_registered()) {
|
||||
purple_debug_info(PLUGIN_ID, "Client is not registered\n");
|
||||
|
||||
if (code && hash) {
|
||||
purple_debug_info(PLUGIN_ID, "SMS code provided, trying to verify \n");
|
||||
purple_debug_info(PLUGIN_ID, "pointer - code:%p hash:%p\n", code, hash);
|
||||
purple_debug_info(PLUGIN_ID, "string - code%s hash:%s\n", code, hash);
|
||||
int verified = network_verify_registration(code, hash);
|
||||
if (verified) {
|
||||
store_config();
|
||||
} else {
|
||||
purple_connection_set_state(gc, PURPLE_DISCONNECTED);
|
||||
purple_notify_message(_telegram_protocol, PURPLE_NOTIFY_MSG_INFO, "Verification Failed",
|
||||
"Please make sure you entered the correct verification code.", NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// TODO: we should find a way to request the key
|
||||
// only once.
|
||||
purple_debug_info(PLUGIN_ID, "Device not registered, requesting new authentication code.\n");
|
||||
char *new_hash = network_request_registration();
|
||||
purple_debug_info(PLUGIN_ID, "Saving verification_hash: '%s'", new_hash);
|
||||
purple_account_set_string(acct, "verification_hash", new_hash);
|
||||
}
|
||||
}
|
||||
|
||||
// Our protocol data, that will be delivered to us
|
||||
// through purple connection
|
||||
telegram_conn *conn = g_new0(telegram_conn, 1);
|
||||
conn->gc = gc;
|
||||
conn->account = acct;
|
||||
|
||||
purple_connection_set_protocol_data(gc, conn);
|
||||
|
||||
gc->proto_data = conn;
|
||||
purple_connection_set_state(gc, PURPLE_CONNECTED);
|
||||
|
||||
purple_debug_info(PLUGIN_ID, "Connected\n");
|
||||
*/
|
||||
|
||||
// TODO: probably needs to be in callback after connection
|
||||
purple_connection_set_state(gc, PURPLE_CONNECTED);
|
||||
purple_debug_info(PLUGIN_ID, "Logged in...\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This must be implemented.
|
||||
*/
|
||||
|
@ -192,6 +195,7 @@ static void tgprpl_close(PurpleConnection * gc)
|
|||
static int tgprpl_send_im(PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags)
|
||||
{
|
||||
purple_debug_info(PLUGIN_ID, "tgprpl_send_im()\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -241,7 +245,6 @@ static void tgprpl_add_buddies(PurpleConnection * gc, GList * buddies, GList * g
|
|||
static void tgprpl_remove_buddy(PurpleConnection * gc, PurpleBuddy * buddy, PurpleGroup * group)
|
||||
{
|
||||
purple_debug_info(PLUGIN_ID, "tgprpl_remove_buddy()\n");
|
||||
|
||||
}
|
||||
|
||||
static void tgprpl_remove_buddies(PurpleConnection * gc, GList * buddies, GList * groups)
|
||||
|
@ -569,8 +572,13 @@ static void tgprpl_init(PurplePlugin *plugin)
|
|||
option = purple_account_option_list_new("Verification type", "verification_type", verification_values);
|
||||
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
|
||||
|
||||
option = purple_account_option_string_new("Server", "server", TELEGRAM_TEST_SERVER);
|
||||
option = purple_account_option_string_new("Verification key", "verification_key", NULL);
|
||||
// option = purple_account_option_string_new("Server", "server", TELEGRAM_TEST_SERVER);
|
||||
// prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
|
||||
|
||||
option = purple_account_option_string_new("Verification key", "verification_key", NULL);
|
||||
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
|
||||
|
||||
option = purple_account_option_string_new("Verification hash", "verification_hash", NULL);
|
||||
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
|
||||
|
||||
// TODO: Path to public key (When you can change the server hostname,
|
||||
|
@ -617,4 +625,5 @@ static PurplePluginInfo info = {
|
|||
NULL // reserved
|
||||
};
|
||||
|
||||
|
||||
PURPLE_INIT_PLUGIN(telegram, tgprpl_init, info)
|
||||
|
|
125
queries.c
125
queries.c
|
@ -126,11 +126,13 @@ void query_restart (long long id) {
|
|||
}
|
||||
|
||||
struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) {
|
||||
logprintf("send_query(...)\n");
|
||||
assert (DC);
|
||||
assert (DC->auth_key_id);
|
||||
if (!DC->sessions[0]) {
|
||||
dc_create_session (DC);
|
||||
}
|
||||
logprintf("telegram: verbosity: %d\n", verbosity);
|
||||
if (verbosity) {
|
||||
logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
|
||||
}
|
||||
|
@ -397,6 +399,7 @@ int send_code_on_answer (struct query *q UU) {
|
|||
tfree_str (phone_code_hash);
|
||||
}
|
||||
phone_code_hash = tstrndup (s, l);
|
||||
logprintf("telegram: phone_code_hash: %s\n", phone_code_hash);
|
||||
fetch_int ();
|
||||
fetch_bool ();
|
||||
want_dc_num = -1;
|
||||
|
@ -434,7 +437,7 @@ int config_got (void) {
|
|||
|
||||
char *suser;
|
||||
extern int dc_working_num;
|
||||
void do_send_code (const char *user) {
|
||||
char* do_send_code (const char *user) {
|
||||
logprintf ("sending code\n");
|
||||
suser = tstrdup (user);
|
||||
want_dc_num = 0;
|
||||
|
@ -450,7 +453,7 @@ void do_send_code (const char *user) {
|
|||
logprintf ("send_code: dc_num = %d\n", dc_working_num);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0);
|
||||
net_loop (0, code_is_sent);
|
||||
if (want_dc_num == -1) { return; }
|
||||
if (want_dc_num == -1) { return phone_code_hash; }
|
||||
|
||||
DC_working = DC_list[want_dc_num];
|
||||
if (!DC_working->sessions[0]) {
|
||||
|
@ -474,6 +477,8 @@ void do_send_code (const char *user) {
|
|||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0);
|
||||
net_loop (0, code_is_sent);
|
||||
assert (want_dc_num == -1);
|
||||
|
||||
return phone_code_hash;
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,12 +631,11 @@ int sign_in_on_answer (struct query *q UU) {
|
|||
fetch_user (&User);
|
||||
if (!our_id) {
|
||||
our_id = get_peer_id (User.id);
|
||||
|
||||
bl_do_set_our_id (our_id);
|
||||
}
|
||||
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 ()));
|
||||
logprintf ( "telegram: 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;
|
||||
|
||||
|
@ -643,7 +647,6 @@ int sign_in_on_answer (struct query *q UU) {
|
|||
int sign_in_on_error (struct query *q UU, int error_code, int l, char *error) {
|
||||
logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error);
|
||||
sign_in_ok = -1;
|
||||
assert (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -652,11 +655,11 @@ struct query_methods sign_in_methods = {
|
|||
.on_error = sign_in_on_error
|
||||
};
|
||||
|
||||
int do_send_code_result (const char *code) {
|
||||
int do_send_code_result (const char *code, const char *sms_hash) {
|
||||
clear_packet ();
|
||||
out_int (CODE_auth_sign_in);
|
||||
out_string (suser);
|
||||
out_string (phone_code_hash);
|
||||
out_string(sms_hash);
|
||||
out_string (code);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0);
|
||||
sign_in_ok = 0;
|
||||
|
@ -698,27 +701,27 @@ int get_contacts_on_answer (struct query *q UU) {
|
|||
struct user *U = fetch_alloc_user ();
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("User #%d: ", get_peer_id (U->id));
|
||||
logprintf ("User #%d: ", get_peer_id (U->id));
|
||||
print_user_name (U->id, (peer_t *)U);
|
||||
push_color (COLOR_GREEN);
|
||||
printf (" (");
|
||||
printf ("%s", U->print_name);
|
||||
logprintf (" (");
|
||||
logprintf ("%s", U->print_name);
|
||||
if (U->phone) {
|
||||
printf (" ");
|
||||
printf ("%s", U->phone);
|
||||
logprintf (" ");
|
||||
logprintf ("%s", U->phone);
|
||||
}
|
||||
printf (") ");
|
||||
logprintf (") ");
|
||||
pop_color ();
|
||||
if (U->status.online > 0) {
|
||||
printf ("online\n");
|
||||
logprintf ("online\n");
|
||||
} else {
|
||||
if (U->status.online < 0) {
|
||||
printf ("offline. Was online ");
|
||||
logprintf ("offline. Was online ");
|
||||
print_date_full (U->status.when);
|
||||
} else {
|
||||
printf ("offline permanent");
|
||||
logprintf ("offline permanent");
|
||||
}
|
||||
printf ("\n");
|
||||
logprintf ("\n");
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
@ -872,9 +875,9 @@ int msg_send_on_answer (struct query *q UU) {
|
|||
}
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Link with user ");
|
||||
logprintf ("Link with user ");
|
||||
print_user_name (U->id, (void *)U);
|
||||
printf (" changed\n");
|
||||
logprintf (" changed\n");
|
||||
pop_color ();
|
||||
print_end ();
|
||||
}
|
||||
|
@ -1175,15 +1178,15 @@ int get_dialogs_on_answer (struct query *q UU) {
|
|||
switch (get_peer_type (plist[i])) {
|
||||
case PEER_USER:
|
||||
UC = user_chat_get (plist[i]);
|
||||
printf ("User ");
|
||||
logprintf ("User ");
|
||||
print_user_name (plist[i], UC);
|
||||
printf (": %d unread\n", dlist[2 * i + 1]);
|
||||
logprintf (": %d unread\n", dlist[2 * i + 1]);
|
||||
break;
|
||||
case PEER_CHAT:
|
||||
UC = user_chat_get (plist[i]);
|
||||
printf ("Chat ");
|
||||
logprintf ("Chat ");
|
||||
print_chat_name (plist[i], UC);
|
||||
printf (": %d unread\n", dlist[2 * i + 1]);
|
||||
logprintf (": %d unread\n", dlist[2 * i + 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1646,21 +1649,21 @@ void print_chat_info (struct chat *C) {
|
|||
peer_t *U = (void *)C;
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Chat ");
|
||||
logprintf ("Chat ");
|
||||
print_chat_name (U->id, U);
|
||||
printf (" members:\n");
|
||||
logprintf (" members:\n");
|
||||
int i;
|
||||
for (i = 0; i < C->user_list_size; i++) {
|
||||
printf ("\t\t");
|
||||
logprintf ("\t\t");
|
||||
print_user_name (MK_USER (C->user_list[i].user_id), user_chat_get (MK_USER (C->user_list[i].user_id)));
|
||||
printf (" invited by ");
|
||||
logprintf (" invited by ");
|
||||
print_user_name (MK_USER (C->user_list[i].inviter_id), user_chat_get (MK_USER (C->user_list[i].inviter_id)));
|
||||
printf (" at ");
|
||||
logprintf (" at ");
|
||||
print_date_full (C->user_list[i].date);
|
||||
if (C->user_list[i].user_id == C->admin_id) {
|
||||
printf (" admin");
|
||||
logprintf (" admin");
|
||||
}
|
||||
printf ("\n");
|
||||
logprintf ("\n");
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
@ -1700,17 +1703,17 @@ void print_user_info (struct user *U) {
|
|||
peer_t *C = (void *)U;
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("User ");
|
||||
logprintf ("User ");
|
||||
print_user_name (U->id, C);
|
||||
printf (":\n");
|
||||
printf ("\treal name: %s %s\n", U->real_first_name, U->real_last_name);
|
||||
printf ("\tphone: %s\n", U->phone);
|
||||
logprintf (":\n");
|
||||
logprintf ("\treal name: %s %s\n", U->real_first_name, U->real_last_name);
|
||||
logprintf ("\tphone: %s\n", U->phone);
|
||||
if (U->status.online > 0) {
|
||||
printf ("\tonline\n");
|
||||
logprintf ("\tonline\n");
|
||||
} else {
|
||||
printf ("\toffline (was online ");
|
||||
logprintf ("\toffline (was online ");
|
||||
print_date_full (U->status.when);
|
||||
printf (")\n");
|
||||
logprintf (")\n");
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
@ -2127,27 +2130,27 @@ int add_contact_on_answer (struct query *q UU) {
|
|||
struct user *U = fetch_alloc_user ();
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("User #%d: ", get_peer_id (U->id));
|
||||
logprintf ("User #%d: ", get_peer_id (U->id));
|
||||
print_user_name (U->id, (peer_t *)U);
|
||||
push_color (COLOR_GREEN);
|
||||
printf (" (");
|
||||
printf ("%s", U->print_name);
|
||||
logprintf (" (");
|
||||
logprintf ("%s", U->print_name);
|
||||
if (U->phone) {
|
||||
printf (" ");
|
||||
printf ("%s", U->phone);
|
||||
logprintf (" ");
|
||||
logprintf ("%s", U->phone);
|
||||
}
|
||||
printf (") ");
|
||||
logprintf (") ");
|
||||
pop_color ();
|
||||
if (U->status.online > 0) {
|
||||
printf ("online\n");
|
||||
logprintf ("online\n");
|
||||
} else {
|
||||
if (U->status.online < 0) {
|
||||
printf ("offline. Was online ");
|
||||
logprintf ("offline. Was online ");
|
||||
print_date_full (U->status.when);
|
||||
} else {
|
||||
printf ("offline permanent");
|
||||
logprintf ("offline permanent");
|
||||
}
|
||||
printf ("\n");
|
||||
logprintf ("\n");
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
@ -2223,11 +2226,11 @@ int contacts_search_on_answer (struct query *q UU) {
|
|||
push_color (COLOR_YELLOW);
|
||||
for (i = 0; i < n; i++) {
|
||||
struct user *U = fetch_alloc_user ();
|
||||
printf ("User ");
|
||||
logprintf ("User ");
|
||||
push_color (COLOR_RED);
|
||||
printf ("%s %s", U->first_name, U->last_name);
|
||||
logprintf ("%s %s", U->first_name, U->last_name);
|
||||
pop_color ();
|
||||
printf (". Phone %s\n", U->phone);
|
||||
logprintf (". Phone %s\n", U->phone);
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
@ -2254,17 +2257,17 @@ int send_encr_accept_on_answer (struct query *q UU) {
|
|||
if (E->state == sc_ok) {
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Encrypted connection with ");
|
||||
logprintf ("Encrypted connection with ");
|
||||
print_encr_chat_name (E->id, (void *)E);
|
||||
printf (" established\n");
|
||||
logprintf (" established\n");
|
||||
pop_color ();
|
||||
print_end ();
|
||||
} else {
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Encrypted connection with ");
|
||||
logprintf ("Encrypted connection with ");
|
||||
print_encr_chat_name (E->id, (void *)E);
|
||||
printf (" failed\n");
|
||||
logprintf (" failed\n");
|
||||
pop_color ();
|
||||
print_end ();
|
||||
}
|
||||
|
@ -2276,17 +2279,17 @@ int send_encr_request_on_answer (struct query *q UU) {
|
|||
if (E->state == sc_deleted) {
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Encrypted connection with ");
|
||||
logprintf ("Encrypted connection with ");
|
||||
print_encr_chat_name (E->id, (void *)E);
|
||||
printf (" can not be established\n");
|
||||
logprintf (" can not be established\n");
|
||||
pop_color ();
|
||||
print_end ();
|
||||
} else {
|
||||
print_start ();
|
||||
push_color (COLOR_YELLOW);
|
||||
printf ("Establishing connection with ");
|
||||
logprintf ("Establishing connection with ");
|
||||
print_encr_chat_name (E->id, (void *)E);
|
||||
printf ("\n");
|
||||
logprintf ("\n");
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
||||
|
@ -2679,12 +2682,12 @@ void do_visualize_key (peer_id_t id) {
|
|||
for (j = 0; j < 4; j ++) {
|
||||
push_color (colors[x & 3]);
|
||||
push_color (COLOR_INVERSE);
|
||||
printf (" ");
|
||||
logprintf (" ");
|
||||
pop_color ();
|
||||
pop_color ();
|
||||
x = x >> 2;
|
||||
}
|
||||
if (i & 1) { printf ("\n"); }
|
||||
if (i & 1) { logprintf ("\n"); }
|
||||
}
|
||||
print_end ();
|
||||
}
|
||||
|
@ -2713,7 +2716,7 @@ int get_suggested_on_answer (struct query *q UU) {
|
|||
peer_t *U = (void *)fetch_alloc_user ();
|
||||
assert (get_peer_id (U->id) == l[2 * i]);
|
||||
print_user_name (U->id, U);
|
||||
printf (" phone %s: %d mutual friends\n", U->user.phone, l[2 * i + 1]);
|
||||
logprintf (" phone %s: %d mutual friends\n", U->user.phone, l[2 * i + 1]);
|
||||
}
|
||||
pop_color ();
|
||||
print_end ();
|
||||
|
|
|
@ -63,9 +63,9 @@ void work_timers (void);
|
|||
|
||||
extern struct query_methods help_get_config_methods;
|
||||
|
||||
void do_send_code (const char *user);
|
||||
char* do_send_code (const char *user);
|
||||
void do_phone_call (const char *user);
|
||||
int do_send_code_result (const char *code);
|
||||
int do_send_code_result (const char *code, const char *sms_hash);
|
||||
double get_double_time (void);
|
||||
|
||||
void do_update_contact_list (void);
|
||||
|
|
33
tg-cli.h
33
tg-cli.h
|
@ -2,6 +2,39 @@
|
|||
|
||||
int tg_login ();
|
||||
|
||||
void running_for_first_time ();
|
||||
|
||||
void parse_config ();
|
||||
void store_config ();
|
||||
|
||||
void read_auth_file ();
|
||||
|
||||
/**
|
||||
* Connect to the telegram network with the given configuration
|
||||
*/
|
||||
void network_connect ();
|
||||
|
||||
/**
|
||||
* Request a registration code
|
||||
*/
|
||||
char* network_request_registration();
|
||||
|
||||
/**
|
||||
* Verify the registration with the given registration code
|
||||
*/
|
||||
int network_verify_registration(const char *code, const char *sms_hash);
|
||||
|
||||
/**
|
||||
* Retur if the current phone is registered in the given network.
|
||||
*/
|
||||
int network_phone_is_registered();
|
||||
|
||||
/**
|
||||
* Return if the current client is registered.
|
||||
*/
|
||||
int network_client_is_registered();
|
||||
|
||||
void set_default_username ();
|
||||
// Settings
|
||||
#define AUTH_MODE_SMS "sms"
|
||||
#define AUTH_MODE_PHONE "phone"
|
||||
|
|
Loading…
Add table
Reference in a new issue