/* the callback function after socket is built * we setup the qq protocol related configuration here */ static void connect_cb(gpointer data, gint source, const gchar *error_message) { PurpleConnection *gc; qq_data *qd; qq_connection *conn; gc = (PurpleConnection *) data; g_return_if_fail(gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; /* conn_data will be destoryed */ qd->conn_data = NULL; if (!PURPLE_CONNECTION_IS_VALID(gc)) { purple_debug_info("QQ_CONN", "Invalid connection\n"); close(source); return; } if (source < 0) { /* socket returns -1 */ purple_debug_info("QQ_CONN", "Could not establish a connection with the server:\n%s\n", error_message); if (qd->connect_watcher > 0) purple_timeout_remove(qd->connect_watcher); qd->connect_watcher = purple_timeout_add_seconds(QQ_CONNECT_INTERVAL, qq_connect_later, gc); return; } /* _qq_show_socket("Got login socket", source); */ /* ok, already connected to the server */ qd->fd = source; conn = connection_create(qd, source); g_return_if_fail( conn != NULL ); if (qd->use_tcp) { /* events which match "PURPLE_INPUT_READ" of * "source" would trigger the callback function */ conn->input_handler = purple_input_add(source, PURPLE_INPUT_READ, tcp_pending, gc); } else { conn->input_handler = purple_input_add(source, PURPLE_INPUT_READ, udp_pending, gc); } g_return_if_fail(qd->network_watcher == 0); qd->network_watcher = purple_timeout_add_seconds(qd->itv_config.resend, network_timeout, gc); set_all_keys( gc ); if (qd->client_version >= 2007) { purple_connection_update_progress(gc, _("Getting server"), 2, QQ_CONNECT_STEPS); /* touch required */ qq_request_get_server(gc); return; } purple_connection_update_progress(gc, _("Requesting token"), 2, QQ_CONNECT_STEPS); qq_request_token(gc); }
static void np_update_account(NPSession *session,gchar *body,gsize body_len,GError **error) { // purple_debug_info("np", "body len"); purple_debug_info("np", "body len : %zd content:",body_len); PurpleAccount *account; PurpleConnection *gc; const gchar *login_string_start; const gchar *login_string_end; gchar *login_string; const char *prefix = "loginString\":\""; const char *suffix = "\"}"; account = session->account; gc = purple_account_get_connection(account); login_string_start = body; login_string_start = strstr(login_string_start, prefix); if (login_string_start) { login_string_end = login_string_start; login_string_end = strstr(login_string_start, suffix); if (login_string_end > login_string_start) { gsize len = login_string_end - login_string_start - strlen(prefix); login_string = g_strndup(login_string_start + strlen(prefix), len); purple_debug_info("np", "login_string: %s",login_string); purple_connection_update_progress(gc, _("Got Token!"), 1, 3); np_socket_login(session); return; } else { goto login_fail; } } else { goto login_fail; } login_fail: purple_connection_update_progress(gc, _("Fail"), 1, 3); }
/*------------------------------------------------------------------------ * Attempt to establish a connection to the MXit server. * * @param session The MXit session object */ static void mxit_login_connect( struct MXitSession* session ) { PurpleProxyConnectData* data = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_login_connect\n" ); purple_connection_update_progress( session->con, _( "Connecting..." ), 1, 4 ); /* * at this stage we have all the user's information we require * for logging into MXit. we will now create a new connection to * a MXit server. */ if ( !session->http ) { /* socket connection */ data = purple_proxy_connect( session->con, session->acc, session->server, session->port, mxit_cb_connect, session ); if ( !data ) { purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) ); return; } } else { /* http connection */ mxit_connected( session ); } }
static void fx_login(PurpleAccount *account) { PurplePresence *presence; PurpleConnection *pc = purple_account_get_connection(account); const gchar *mobileno = purple_account_get_username(account); const gchar *password = purple_connection_get_password(pc); const gchar *status_id; fetion_account *ac = session_new(account); /* construct a user object */ ac->user = fetion_user_new(mobileno, password); ac->account = account; ac->gc = pc; ac->chan_ready = 1; purple_connection_set_protocol_data(pc, ac); presence = purple_account_get_presence(account); status_id = get_status_id(ac->user->state); if(ac->user->state == 0) status_id = "Hidden"; purple_presence_set_status_active(presence, status_id, TRUE); purple_connection_update_progress(pc, "Connecting", 1, 2); purple_ssl_connect(ac->account, SSI_SERVER, PURPLE_SSL_DEFAULT_PORT, (PurpleSslInputFunction)ssi_auth_action, (PurpleSslErrorFunction)0, ac); }
static void fb_login(PurpleAccount *account) { FacebookAccount *fba; gchar *postdata, *encoded_username, *encoded_password, *encoded_charset_test; const gchar* const *languages; const gchar *locale; /* Create account and initialize state */ fba = g_new0(FacebookAccount, 1); fba->account = account; fba->pc = purple_account_get_connection(account); fba->uid = -1; fba->last_messages_download_time = time(NULL) - 60; /* 60 secs is a safe buffer */ fba->cookie_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); fba->hostname_ip_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); fba->sent_messages_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); fba->auth_buddies = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); g_hash_table_replace(fba->cookie_table, g_strdup("test_cookie"), g_strdup("1")); account->gc->proto_data = fba; /* Error localized in libpurple jabber.c */ if (!purple_ssl_is_supported()) { purple_connection_error_reason (purple_account_get_connection(account), PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("Server requires TLS/SSL for login. No TLS/SSL support found.")); return; } purple_connection_set_state(fba->pc, PURPLE_CONNECTING); purple_connection_update_progress(fba->pc, _("Connecting"), 1, 3); encoded_username = g_strdup(purple_url_encode( purple_account_get_username(fba->account))); encoded_password = g_strdup(purple_url_encode( purple_account_get_password(fba->account))); encoded_charset_test = g_strdup(purple_url_encode("€,´,€,´,水,Д,Є")); languages = g_get_language_names(); locale = languages[0]; if (locale == NULL || g_str_equal(locale, "C")) locale = "en_US"; g_hash_table_replace(fba->cookie_table, g_strdup("lsd"), g_strdup("abcde")); postdata = g_strdup_printf( "charset_test=%s&locale=%s&email=%s&pass=%s&pass_placeHolder=Password&persistent=1&login=Login&charset_test=%s&lsd=abcde", encoded_charset_test, locale, encoded_username, encoded_password, encoded_charset_test); g_free(encoded_username); g_free(encoded_password); g_free(encoded_charset_test); fb_post_or_get(fba, FB_METHOD_POST | FB_METHOD_SSL, "login.facebook.com", "/login.php?login_attempt=1&_fb_noscript=1", postdata, fb_login_cb, NULL, FALSE); g_free(postdata); }
gboolean connect_to_server(PurpleConnection *gc, gchar *server, gint port) { PurpleAccount *account ; qq_data *qd; g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE); account = purple_connection_get_account(gc); qd = (qq_data *) gc->proto_data; if (server == NULL || server[0] == '\0' || port == 0) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid server or port")); return FALSE; } purple_connection_update_progress(gc, _("Connecting to server"), 1, QQ_CONNECT_STEPS); purple_debug_info("QQ", "Connect to %s:%d\n", server, port); if (qd->conn_data != NULL) { purple_proxy_connect_cancel(qd->conn_data); qd->conn_data = NULL; } #ifdef purple_proxy_connect_udp if (qd->use_tcp) { qd->conn_data = purple_proxy_connect(gc, account, server, port, connect_cb, gc); } else { qd->conn_data = purple_proxy_connect_udp(gc, account, server, port, connect_cb, gc); } if ( qd->conn_data == NULL ) { purple_debug_error("QQ", "Couldn't create socket\n"); return FALSE; } #else /* QQ connection via UDP/TCP. * Now use Purple proxy function to provide TCP proxy support, * and qq_udp_proxy.c to add UDP proxy support (thanks henry) */ if(qd->use_tcp) { qd->conn_data = purple_proxy_connect(gc, account, server, port, connect_cb, gc); if ( qd->conn_data == NULL ) { purple_debug_error("QQ", "Unable to connect.\n"); return FALSE; } return TRUE; } purple_debug_info("QQ", "UDP Connect to %s:%d\n", server, port); qd->udp_query_data = purple_dnsquery_a(server, port, udp_host_resolved, gc); if ( qd->udp_query_data == NULL ) { purple_debug_error("QQ", "Could not resolve hostname\n"); return FALSE; } #endif return TRUE; }
static void np_login(PurpleAccount *account) { PurpleConnection *gc; NPSession *session; PurplePresence *presence; const char *host; gboolean http_method = FALSE; int port; purple_debug_warning("np","\n===> %p ",account); purple_debug_warning("np","account->alias = %s\n",account->alias); purple_debug_warning("np","account->username = %s\n",account->username); purple_debug_warning("np","account->password = %s\n",account->password); purple_debug_warning("np","account->user_info = %s\n",account->user_info); g_return_if_fail(account != NULL); session = np_session_new(account); gc = purple_account_get_connection(account); g_return_if_fail(gc != NULL); const char *http_server = purple_account_get_string(session->account, "http_method_server", NP_HTTPCONN_SERVER); purple_debug_info("np", "http_server: %s",http_server); purple_connection_set_state(gc, PURPLE_CONNECTING); purple_connection_update_progress(gc, _("Connecting"), 1, 3); np_http_login0(session, np_http_login0_cb); return; /* host = purple_account_get_string(account, "server", NP_IM_SERVER); port = purple_account_get_int(account, "port", NP_IM_PORT); session = np_session_new(account); purple_debug_warning("np","=====> session : %p ",session); gc = purple_account_get_connection(account); g_return_if_fail(gc != NULL); gc->proto_data = session; gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_AUTO_RESP; np_session_set_login_step(session, NP_LOGIN_STEP_START); presence = purple_account_get_presence(account); if (!np_session_connect(session, host, port, http_method)) purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); */ }
static void irc_login(PurpleAccount *account) { PurpleConnection *gc; struct irc_conn *irc; char **userparts; const char *username = purple_account_get_username(account); gc = purple_account_get_connection(account); gc->flags |= PURPLE_CONNECTION_NO_NEWLINES; if (strpbrk(username, " \t\v\r\n") != NULL) { purple_connection_error(gc, _("IRC nicks may not contain whitespace")); return; } gc->proto_data = irc = g_new0(struct irc_conn, 1); irc->fd = -1; irc->account = account; irc->outbuf = purple_circ_buffer_new(512); userparts = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userparts[0]); irc->server = g_strdup(userparts[1]); g_strfreev(userparts); irc->buddies = g_hash_table_new_full((GHashFunc)irc_nick_hash, (GEqualFunc)irc_nick_equal, NULL, (GDestroyNotify)irc_buddy_free); irc->cmds = g_hash_table_new(g_str_hash, g_str_equal); irc_cmd_table_build(irc); irc->msgs = g_hash_table_new(g_str_hash, g_str_equal); irc_msg_table_build(irc); purple_connection_update_progress(gc, _("Connecting"), 1, 2); if (purple_account_get_bool(account, "ssl", FALSE)) { if (purple_ssl_is_supported()) { irc->gsc = purple_ssl_connect(account, irc->server, purple_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT), irc_login_cb_ssl, irc_ssl_connect_failure, gc); } else { purple_connection_error(gc, _("SSL support unavailable")); return; } } if (!irc->gsc) { if (purple_proxy_connect(gc, account, irc->server, purple_account_get_int(account, "port", IRC_DEFAULT_PORT), irc_login_cb, gc) == NULL) { purple_connection_error(gc, _("Couldn't create socket")); return; } } }
void skypeweb_begin_oauth_login(SkypeWebAccount *sa) { const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST "/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, NULL, TRUE, 524288, skypeweb_login_got_ppft, sa); purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTING); purple_connection_update_progress(sa->pc, _("Connecting"), 1, 4); }
static void nullprpl_login(PurpleAccount *acct) { PurpleConnection *gc = purple_account_get_connection(acct); GList *offline_messages; purple_debug_info("nullprpl", "logging in %s\n", purple_account_get_username(acct)); purple_connection_update_progress(gc, _("Connecting"), 0, /* which connection step this is */ 2); /* total number of steps */ purple_connection_update_progress(gc, _("Connected"), 1, /* which connection step this is */ 2); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED); /* tell purple about everyone on our buddy list who's connected */ foreach_nullprpl_gc(discover_status, gc, NULL); /* notify other nullprpl accounts */ foreach_nullprpl_gc(report_status_change, gc, NULL); /* fetch stored offline messages */ purple_debug_info("nullprpl", "checking for offline messages for %s\n", purple_account_get_username(acct)); offline_messages = g_hash_table_lookup(goffline_messages, purple_account_get_username(acct)); while (offline_messages) { GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; purple_debug_info("nullprpl", "delivering offline message to %s: %s\n", purple_account_get_username(acct), message->message); purple_serv_got_im(gc, message->from, message->message, message->flags, message->mtime); offline_messages = g_list_next(offline_messages); g_free(message->from); g_free(message->message); g_free(message); } g_list_free(offline_messages); g_hash_table_remove(goffline_messages, purple_account_get_username(acct)); }
/*------------------------------------------------------------------------ * We now have a connection established with MXit, so we can start the * login procedure * * @param session The MXit session object */ static void mxit_connected( struct MXitSession* session ) { int state; purple_debug_info( MXIT_PLUGIN_ID, "mxit_connected\n" ); session->flags |= MXIT_FLAG_CONNECTED; purple_connection_update_progress( session->con, _( "Logging In..." ), 2, 4 ); /* create a timer to send a ping packet if the connection is idle */ session->last_tx = mxit_now_milli(); /* encrypt the user password */ session->encpwd = mxit_encrypt_password( session ); state = purple_account_get_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); if ( state == MXIT_STATE_LOGIN ) { /* create and send login packet */ mxit_send_login( session ); } else { if ( !session->profile ) { /* we have lost the session profile, so ask the user to enter it again */ mxit_register_view( session ); } else { /* create and send the register packet */ mxit_send_register( session ); } } /* enable signals */ mxit_enable_signals( session ); #ifdef MXIT_LINK_CLICK /* register for uri click notification */ mxit_register_uri_handler(); #endif /* start the polling if this is a HTTP connection */ if ( session->http ) { session->http_timer_id = purple_timeout_add_seconds( 2, mxit_manage_polling, session ); } /* This timer might already exist if we're registering a new account */ if ( session->q_slow_timer_id == 0 ) { /* start the tx queue manager timer */ session->q_slow_timer_id = purple_timeout_add_seconds( 2, mxit_manage_queue_slow, session ); } }
static void nap_login(PurpleAccount *account) { PurpleConnection *gc = purple_account_get_connection(account); purple_connection_update_progress(gc, _("Connecting"), 0, NAPSTER_CONNECT_STEPS); gc->proto_data = g_new0(struct nap_data, 1); if (purple_proxy_connect(gc, account, purple_account_get_string(account, "server", NAP_SERVER), purple_account_get_int(account, "port", NAP_PORT), nap_login_connect, gc) != 0) { purple_connection_error(gc, _("Unable to connect.")); } }
static void waprpl_login(PurpleAccount * acct) { PurpleConnection *gc = purple_account_get_connection(acct); purple_debug_info(WHATSAPP_ID, "logging in %s\n", purple_account_get_username(acct)); purple_connection_update_progress(gc, "Connecting", 0, 4); whatsapp_connection *wconn = g_new0(whatsapp_connection, 1); wconn->fd = -1; wconn->sslfd = -1; wconn->account = acct; wconn->rh = 0; wconn->wh = 0; wconn->timer = 0; wconn->connected = 0; wconn->conv_id = 1; wconn->gsc = 0; wconn->sslrh = 0; wconn->sslwh = 0; const char *username = purple_account_get_username(acct); const char *password = purple_account_get_password(acct); const char *nickname = purple_account_get_string(acct, "nick", ""); wconn->waAPI = waAPI_create(username, password, nickname); purple_connection_set_protocol_data(gc, wconn); const char *hostname = purple_account_get_string(acct, "server", ""); int port = purple_account_get_int(acct, "port", WHATSAPP_DEFAULT_PORT); char hn[256]; if (strlen(hostname) == 0) { sprintf(hn, "e%d.whatsapp.net", rand() % 9 + 1); hostname = hn; } if (purple_proxy_connect(gc, acct, hostname, port, waprpl_connect_cb, gc) == NULL) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Unable to connect"); } static int sig_con = 0; if (!sig_con) { sig_con = 1; purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", _whatsapp_protocol, PURPLE_CALLBACK(waprpl_blist_node_removed), NULL); purple_signal_connect(purple_blist_get_handle(), "blist-node-added", _whatsapp_protocol, PURPLE_CALLBACK(waprpl_blist_node_added), NULL); } }
static void skypeweb_login_got_t(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebAccount *sa = user_data; const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST;// "/login/oauth?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; gchar *request; GString *postdata; gchar *magic_t_value; // T is for tasty sa->url_datas = g_slist_remove(sa->url_datas, url_data); // <input type="hidden" name="t" id="t" value="..."> magic_t_value = skypeweb_string_get_chunk(url_text, len, "=\"t\" value=\"", "\""); if (!magic_t_value) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting Magic T value")); return; } // postdata: t=...&oauthPartner=999&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com postdata = g_string_new(""); g_string_append_printf(postdata, "t=%s&", purple_url_encode(magic_t_value)); g_string_append(postdata, "oauthPartner=999&"); g_string_append(postdata, "client_id=578134&"); g_string_append(postdata, "redirect_uri=https%3A%2F%2Fweb.skype.com"); // post the t to https://login.skype.com/login/oauth?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com request = g_strdup_printf("POST /login/microsoft?client_id=578134&redirect_uri=https%%3A%%2F%%2Fweb.skype.com HTTP/1.0\r\n" "Connection: close\r\n" "Accept: */*\r\n" "BehaviorOverride: redirectAs404\r\n" "Host: " SKYPEWEB_LOGIN_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", strlen(postdata->str), postdata->str); skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa); g_string_free(postdata, TRUE); g_free(request); g_free(magic_t_value); purple_connection_update_progress(sa->pc, _("Verifying"), 3, 4); }
void msn_session_set_login_step(MsnSession *session, MsnLoginStep step) { PurpleConnection *gc; /* Prevent the connection progress going backwards, eg. if we get * transferred several times during login */ if (session->login_step >= step) return; /* If we're already logged in, we're probably here because of a * mid-session XFR from the notification server, so we don't want to * popup the connection progress dialog */ if (session->logged_in) return; gc = purple_account_get_connection(session->account); session->login_step = step; purple_connection_update_progress(gc, get_login_step_text(session), step, MSN_LOGIN_STEPS); }
/* 002 - MSG_CLIENT_LOGIN */ static void nap_login_connect(gpointer data, gint source, const gchar *error_message) { PurpleConnection *gc = data; struct nap_data *ndata = (struct nap_data *)gc->proto_data; gchar *buf; if (!g_list_find(purple_connections_get_all(), gc)) { close(source); return; } if (source < 0) { purple_connection_error(gc, _("Unable to connect.")); return; } /* Clear the nonblocking flag This protocol should be updated to support nonblocking I/O if anyone is going to actually use it */ fcntl(source, F_SETFL, 0); ndata->fd = source; /* Update the login progress status display */ buf = g_strdup_printf("Logging in: %s", purple_account_get_username(gc->account)); purple_connection_update_progress(gc, buf, 1, NAPSTER_CONNECT_STEPS); g_free(buf); /* Write our signon data */ nap_write_packet(gc, 2, "%s %s 0 \"purple %s\" 0", purple_account_get_username(gc->account), purple_connection_get_password(gc), PP_VERSION); /* And set up the input watcher */ gc->inpa = purple_input_add(ndata->fd, PURPLE_INPUT_READ, nap_callback, gc); }
static void skypeweb_login_got_ppft(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebAccount *sa = user_data; const gchar *live_login_url = "https://login.live.com";// "/ppsecure/post.srf?wa=wsignin1.0&wreply=https%3A%2F%2Fsecure.skype.com%2Flogin%2Foauth%2Fproxy%3Fclient_id%3D578134%26redirect_uri%3Dhttps%253A%252F%252Fweb.skype.com"; gchar *msprequ_cookie; gchar *mspok_cookie; gchar *cktst_cookie; gchar *ppft; GString *postdata; gchar *request; // grab PPFT and cookies (MSPRequ, MSPOK) msprequ_cookie = skypeweb_string_get_chunk(url_text, len, "Set-Cookie: MSPRequ=", ";"); if (!msprequ_cookie) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting MSPRequ cookie")); return; } mspok_cookie = skypeweb_string_get_chunk(url_text, len, "Set-Cookie: MSPOK=", ";"); if (!mspok_cookie) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting MSPOK cookie")); return; } // <input type="hidden" name="PPFT" id="i0327" value="..."/> ppft = skypeweb_string_get_chunk(url_text, len, "name=\"PPFT\" id=\"i0327\" value=\"", "\""); if (!ppft) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting PPFT value")); return; } // CkTst=G + timestamp e.g. G1422309314913 cktst_cookie = g_strdup_printf("G%" G_GINT64_FORMAT, skypeweb_get_js_time()); // postdata: login={username}&passwd={password}&PPFT={ppft value} postdata = g_string_new(""); g_string_append_printf(postdata, "login=%s&", purple_url_encode(purple_account_get_username(sa->account))); g_string_append_printf(postdata, "passwd=%s&", purple_url_encode(purple_account_get_password(sa->account))); g_string_append_printf(postdata, "PPFT=%s&", purple_url_encode(ppft)); // POST to https://login.live.com/ppsecure/post.srf?wa=wsignin1.0&wreply=https%3A%2F%2Fsecure.skype.com%2Flogin%2Foauth%2Fproxy%3Fclient_id%3D578134%26redirect_uri%3Dhttps%253A%252F%252Fweb.skype.com request = g_strdup_printf("POST /ppsecure/post.srf?wa=wsignin1.0&wp=MBI_SSL&wreply=https%%3A%%2F%%2Fsecure.skype.com%%2Flogin%%2Foauth%%2Fproxy%%3Fclient_id%%3D578134%%26redirect_uri%%3Dhttps%%253A%%252F%%252Fweb.skype.com HTTP/1.0\r\n" "Connection: close\r\n" "Accept: */*\r\n" "Host: login.live.com\r\n" "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" "Cookie: MSPRequ=%s;MSPOK=%s;CkTst=%s;\r\n" "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", msprequ_cookie, mspok_cookie, cktst_cookie, strlen(postdata->str), postdata->str); purple_util_fetch_url_request(sa->account, live_login_url, TRUE, NULL, FALSE, request, FALSE, 524288, skypeweb_login_got_t, sa); g_string_free(postdata, TRUE); g_free(request); g_free(msprequ_cookie); g_free(mspok_cookie); g_free(cktst_cookie); g_free(ppft); purple_connection_update_progress(sa->pc, _("Authenticating"), 2, 4); }
static void plainprpl_login(PurpleAccount *account) { PurpleConnection *gc = purple_account_get_connection(account); purple_debug_info("plainprpl", "logging in %s\n", account->username); purple_connection_update_progress(gc, _("Connecting"), 0, 2); purple_connection_update_progress(gc, _("Connected"), 1, 2); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Setup plugin data */ plain_plugin_state *pstate = g_new0(plain_plugin_state, 1); /* General account data */ const char *listen_af = purple_account_get_string(account, "listen_af", NULL); const char *listen_port = purple_account_get_string(account, "listen_port", NULL); //check port if (listen_port == NULL || atoi(listen_port) < 1 || atoi(listen_port) >= 65535) { listen_port = PLAIN_DEFAULT_PORT_STR; purple_account_set_string(account, "listen_port", listen_port); } //check protocol if (listen_af == NULL || (strcmp(listen_af, "ipv4") && strcmp(listen_af, "ipv6"))) { listen_af = "ipv4"; purple_account_set_string(account, "listen_port", listen_af); } /* Select the address to listen on */ const char *listen_addr = (strcmp(listen_af, "ipv4") == 0) ? "0.0.0.0" : "::1"; pstate->sockaf = str_to_af(listen_af); pstate->sockfd = net_bind("plainprpl", listen_addr, listen_port, NULL, IPPROTO_UDP, pstate->sockaf); if (pstate->sockfd < 0) { purple_debug_info("plainprpl", "Failed to bind to %s\n", listen_addr); g_free(pstate); //TODO: diable plugin return; } else { purple_debug_info("plainprpl", "Bind to %s\n", listen_addr); } pstate->receive_timer = purple_timeout_add(80, plain_receive, gc); purple_connection_set_protocol_data(gc, pstate); /* Attach buddy data to each buddy */ GSList *list = purple_find_buddies(account, NULL); purple_debug_info("plainprpl", "Buddies to load: %d\n", g_slist_length(list)); GSList *iter = list; while (iter) { PurpleBuddy *buddy = iter->data; //purple_debug_info("plainprpl", "#plainprpl_login: attach custom data to buddy: %s\n", buddy->name); assert(purple_buddy_get_protocol_data(buddy) == NULL); const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str"); if (addr_str != NULL && strlen(addr_str)) { add_buddy_sdata(buddy, pstate); } else { purple_debug_info("plainprpl", "Empty address for buddy: %s\n", buddy->name); } /* Set offline by default */ purple_prpl_got_user_status(account, buddy->name, PLAIN_STATUS_OFFLINE, NULL); iter = iter->next; } g_slist_free(list); /* Call the on_login script - if it is set */ const char *on_login = purple_account_get_string(account, "on_login", NULL); exec_process(on_login, NULL, NULL, gc, NULL); }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; char *msg, *who, *prev, *url, *author; int status; int size; double lat, lng; unsigned long timestamp; /* Incoming messages */ while (1) { int r = waAPI_querynext(wconn->waAPI); switch (r) { case 0: if (waAPI_querychat(wconn->waAPI, &who, &msg, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who, msg); conv_add_message(gc, who, msg, author, timestamp); } break; case 1: if (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who, url); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a><br/><a href=\"%s\">%s</a>", url, imgid, url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 2: if (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who, (float)lat, (float)lng); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>", lat, lng, imgid); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 3: if (waAPI_querychatsound(wconn->waAPI, &who, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who, url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; default: break; }; if (r < 0) break; } /* User status change */ while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message", "", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message", "", NULL); } } /* User typing info notify */ while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { purple_debug_info(WHATSAPP_ID, "%s is typing\n", who); serv_got_typing(gc, who, 0, PURPLE_TYPING); } else { purple_debug_info(WHATSAPP_ID, "%s is not typing\n", who); serv_got_typing(gc, who, 0, PURPLE_NOT_TYPING); serv_got_typing_stopped(gc, who); } } /* User profile picture */ char *icon, *hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc, who, g_memdup(icon, len), len, hash); } /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } }
void fetion_login(PurpleAccount * account) { PurpleConnection *gc; struct fetion_account_data *sip; gchar **userserver; gint ret; const char *username = purple_account_get_username(account); gc = purple_account_get_connection(account); gc->proto_data = sip = g_new0(struct fetion_account_data, 1); sip->gc = gc; sip->tg = 0; //temp group chat id sip->cseq = 0; sip->account = account; sip->registerexpire = 400; sip->reregister = time(NULL) + 100; sip->txbuf = purple_circ_buffer_new(0); sip->impresa = NULL; sip->icon_buf = purple_circ_buffer_new(0); sip->GetContactFlag = 0; purple_debug_info("Fetion:", "shit\n"); userserver = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userserver[0]); if (IsCMccNo(userserver[0])) { sip->username = NULL; sip->mobileno = g_strdup(userserver[0]); } else { sip->mobileno = NULL; sip->username = g_strdup(userserver[0]); } // sip->servername = g_strdup(userserver[1]); sip->SysCfgServer = g_strdup("nav.fetion.com.cn"); sip->password = g_strdup(purple_connection_get_password(gc)); g_strfreev(userserver); sip->buddies = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->tempgroup = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->group = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->group2id = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); purple_connection_update_progress(gc, _("Connecting"), 1, 2); /* TODO: Set the status correctly. */ sip->status = g_strdup("available"); sip->registertimeout = purple_timeout_add(60000, (GSourceFunc) LoginToSsiPortal, sip); //Try to get systemconfig sip->ServerVersion = NULL; sip->ServiceNoVersion = NULL; sip->ParaVersion = NULL; sip->HttpAppVersion = NULL; sip->ClientCfgVersion = NULL; sip->HintsVersion = NULL; ret = ParseCfg(sip); //if(ret!=0) sip->SysCfg.conn = purple_proxy_connect(NULL, sip->account, sip->SysCfgServer, 80, (PurpleProxyConnectFunction) RetriveSysCfg, sip); }
gboolean silcpurple_check_silc_dir(PurpleConnection *gc) { char filename[256], file_public_key[256], file_private_key[256]; char servfilename[256], clientfilename[256], friendsfilename[256]; char pkd[256], prd[256]; struct stat st; struct passwd *pw; int fd; pw = getpwuid(getuid()); if (!pw) { purple_debug_error("silc", "silc: %s\n", g_strerror(errno)); return FALSE; } g_snprintf(filename, sizeof(filename) - 1, "%s", silcpurple_silcdir()); g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys", silcpurple_silcdir()); g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys", silcpurple_silcdir()); g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends", silcpurple_silcdir()); if (pw->pw_uid != geteuid()) { purple_debug_error("silc", "Couldn't create directories due to wrong uid!\n"); return FALSE; } /* * Check ~/.silc directory */ if (g_mkdir(filename, 0755) != 0 && errno != EEXIST) { purple_debug_error("silc", "Couldn't create '%s' directory\n", filename); return FALSE; } #ifndef _WIN32 if ((g_stat(filename, &st)) == -1) { purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, g_strerror(errno)); return FALSE; } else { /* Check the owner of the dir */ if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { purple_debug_error("silc", "You don't seem to own '%s' directory\n", filename); return FALSE; } } #endif /* * Check ~./silc/serverkeys directory */ if (g_mkdir(servfilename, 0755) != 0 && errno != EEXIST) { purple_debug_error("silc", "Couldn't create '%s' directory\n", servfilename); return FALSE; } /* * Check ~./silc/clientkeys directory */ if (g_mkdir(clientfilename, 0755) != 0 && errno != EEXIST) { purple_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename); return FALSE; } /* * Check ~./silc/friends directory */ if (g_mkdir(friendsfilename, 0755) != 0 && errno != EEXIST) { purple_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename); return FALSE; } /* * Check Public and Private keys */ g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir()); g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir()); g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s", purple_account_get_string(gc->account, "public-key", pkd)); g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s", purple_account_get_string(gc->account, "private-key", prd)); if ((g_stat(file_public_key, &st)) == -1) { /* If file doesn't exist */ if (errno == ENOENT) { purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, SILCPURPLE_DEF_PKCS_LEN, file_public_key, file_private_key, NULL, (gc->password == NULL) ? "" : gc->password, NULL, NULL, FALSE)) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to create SILC key pair")); return FALSE; } if ((g_stat(file_public_key, &st)) == -1) { purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", file_public_key, g_strerror(errno)); return FALSE; } } else { purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", file_public_key, g_strerror(errno)); return FALSE; } } #ifndef _WIN32 /* Check the owner of the public key */ if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { purple_debug_error("silc", "You don't seem to own your public key!?\n"); return FALSE; } #endif if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) { if ((fstat(fd, &st)) == -1) { purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", file_private_key, g_strerror(errno)); close(fd); return FALSE; } } else { /* If file doesn't exist */ if (errno == ENOENT) { purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, SILCPURPLE_DEF_PKCS_LEN, file_public_key, file_private_key, NULL, (gc->password == NULL) ? "" : gc->password, NULL, NULL, FALSE)) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to create SILC key pair")); return FALSE; } if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) { if ((fstat(fd, &st)) == -1) { purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", file_private_key, g_strerror(errno)); close(fd); return FALSE; } } else { purple_debug_error("silc", "Couldn't open '%s' " "private key, error: %s\n", file_private_key, g_strerror(errno)); return FALSE; } } else { purple_debug_error("silc", "Couldn't open '%s' private key, error: %s\n", file_private_key, g_strerror(errno)); return FALSE; } } #ifndef _WIN32 /* Check the owner of the private key */ if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { purple_debug_error("silc", "You don't seem to own your private key!?\n"); if (fd != -1) close(fd); return FALSE; } /* Check the permissions for the private key */ if ((st.st_mode & 0777) != 0600) { purple_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n" "Trying to change them ...\n", file_private_key); if ((fd == -1) || (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) { purple_debug_error("silc", "Failed to change permissions for private key file!\n" "Permissions for your private key file must be 0600.\n"); if (fd != -1) close(fd); return FALSE; } purple_debug_warning("silc", "Done.\n\n"); } #endif if (fd != -1) close(fd); return TRUE; }
static void skypeweb_login_got_t(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebAccount *sa = user_data; const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST;// "/login/oauth?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; gchar *request; GString *postdata; gchar *magic_t_value; // T is for tasty sa->url_datas = g_slist_remove(sa->url_datas, url_data); // <input type="hidden" name="t" id="t" value="..."> magic_t_value = skypeweb_string_get_chunk(url_text, len, "=\"t\" value=\"", "\""); if (!magic_t_value) { //No Magic T???? Maybe it be the mighty 2fa-beast if (FALSE) /*if (g_strnstr(url_text, len, "Set-Cookie: LOpt=0;"))*/ { //XX - Would this be better retrieved with JSON decoding the "var ServerData = {...}" code? // <script type="text/javascript">var ServerData = {...};</script> gchar *session_state = skypeweb_string_get_chunk(url_text, len, ":'https://login.live.com/GetSessionState.srf?", "',"); if (session_state) { //These two appear to have different object keys each request :( gchar *PPFT = skypeweb_string_get_chunk(url_text, len, ",sFT:'", "',"); gchar *SLK = skypeweb_string_get_chunk(url_text, len, ",aB:'", "',"); gchar *ppauth_cookie = skypeweb_string_get_chunk(url_text, len, "Set-Cookie: PPAuth=", ";"); gchar *mspok_cookie = skypeweb_string_get_chunk(url_text, len, "Set-Cookie: MSPOK=", "; domain="); //Poll https://login.live.com/GetSessionState.srv?{session_state} to retrieve GIF(!!) of 2fa status //1x1 size GIF means pending, 2x2 rejected, 1x2 approved //Then re-request the MagicT, if approved with a slightly different GET parameters //purpose=eOTT_OneTimePassword&PPFT={ppft}&login={email}&SLK={slk} return; } } purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting Magic T value")); return; } // postdata: t=...&oauthPartner=999&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com postdata = g_string_new(""); g_string_append_printf(postdata, "t=%s&", purple_url_encode(magic_t_value)); g_string_append(postdata, "site_name=lw.skype.com&"); g_string_append(postdata, "oauthPartner=999&"); g_string_append(postdata, "client_id=578134&"); g_string_append(postdata, "redirect_uri=https%3A%2F%2Fweb.skype.com"); // post the t to https://login.skype.com/login/oauth?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com request = g_strdup_printf("POST /login/microsoft?client_id=578134&redirect_uri=https%%3A%%2F%%2Fweb.skype.com HTTP/1.0\r\n" "Connection: close\r\n" "Accept: */*\r\n" "BehaviorOverride: redirectAs404\r\n" "Host: " SKYPEWEB_LOGIN_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", strlen(postdata->str), postdata->str); skypeweb_fetch_url_request(sa, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa); g_string_free(postdata, TRUE); g_free(request); g_free(magic_t_value); purple_connection_update_progress(sa->pc, _("Verifying"), 3, 4); }
static void fb_login_cb(FacebookAccount *fba, gchar *response, gsize len, gpointer userdata) { gchar *user_cookie; const gchar *persist_data_start; gchar *persist_data; const gchar *session_start; gchar *session; gchar *captcha_url; const gchar *extra_challenge_params; gchar *extra_challenge; if (len && g_strstr_len(response, len, "captcha")) { purple_debug_info("facebook", "captcha page: %s\n", response); purple_connection_update_progress(fba->pc, _("Handling Captcha"), 2, 4); persist_data_start = "<input type=\"hidden\" id=\"captcha_persist_data\" name=\"captcha_persist_data\" value=\""; persist_data = g_strstr_len(response, len, persist_data_start); if (persist_data) { persist_data += strlen(persist_data_start); fba->persist_data = g_strndup(persist_data, strchr(persist_data, '"') - persist_data); } session_start = "<input type=\"hidden\" id=\"captcha_session\" name=\"captcha_session\" value=\""; session = g_strstr_len(response, len, session_start); if (session) { session += strlen(session_start); fba->captcha_session = g_strndup(session, strchr(session, '"') - session); } extra_challenge_params = "<input type=\"hidden\" id=\"extra_challenge_params\" name=\"extra_challenge_params\" value=\""; extra_challenge = g_strstr_len(response, len, extra_challenge_params); if (extra_challenge) { extra_challenge += strlen(extra_challenge_params); fba->extra_challenge = g_strndup(extra_challenge, strchr(extra_challenge, '"') - extra_challenge); extra_challenge = purple_unescape_html(fba->extra_challenge); g_free(fba->extra_challenge); fba->extra_challenge = extra_challenge; } if (!fba->extra_challenge || !fba->persist_data || !fba->captcha_session) { purple_debug_info("facebook", "captcha response: %s\n", response); g_free(fba->extra_challenge); g_free(fba->persist_data); g_free(fba->captcha_session); fba->extra_challenge = NULL; fba->persist_data = NULL; fba->captcha_session = NULL; purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, "Could not authenticate captcha. Logging into the Facebook website may fix this."); return; } captcha_url = g_strdup_printf("/challenge?k=" FACEBOOK_CAPTCHA_SITE "&%s", fba->extra_challenge?fba->extra_challenge:""); fb_post_or_get(fba, FB_METHOD_GET | FB_METHOD_SSL, "api-secure.recaptcha.net", captcha_url, NULL, fb_login_captcha_cb, NULL, FALSE); g_free(captcha_url); return; } purple_connection_update_progress(fba->pc, _("Authenticating"), 2, 3); /* Look for our uid */ user_cookie = g_hash_table_lookup(fba->cookie_table, "c_user"); if (user_cookie == NULL) { /* * Server didn't set the c_user cookie, so we must have given * them a bad username or password */ purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect username or password.")); return; } fba->uid = atoll(user_cookie); purple_debug_info("facebook", "uid %" G_GINT64_FORMAT "\n", fba->uid); /* ok, we're logged in now! */ purple_connection_set_state(fba->pc, PURPLE_CONNECTED); /* This will kick off our long-poll message retrieval loop */ fb_get_post_form_id(fba); fb_check_friend_requests(fba); /* periodically check for people adding you to their facebook friend list */ fba->friend_request_timer = purple_timeout_add_seconds(60 * 5, fb_check_friend_requests, fba); /* periodically check for new notifications */ fba->notifications_timer = purple_timeout_add_seconds(60, (GSourceFunc)fb_get_notifications_feed, fba); /* Periodically check for new messages. NOTE: This MUST exist, * regardless of other other mechanisms for checking messages. This * is because the code needs a failsafe checker in case other one of * the other retrieval mechanisms dies due to a bad request, etc. * Without such a failsafe, a user will receive no messages, which is * one of hardest bugs to debug and get reports about. Hence, the * importance of this loop. * That said, there is room for tweaking this loop and possibly even * setting it such that it is the primary or only message checker. * The key is that the method must NEVER die until logout. */ fba->perpetual_messages_timer = purple_timeout_add_seconds(15, (GSourceFunc)fb_get_messages_failsafe, fba); /* init blist subsystem */ fb_blist_init(fba); /* init conversation subsystem */ fb_conversation_init(fba); }
static void waprpl_process_incoming_events(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount * acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending auth", 1, 4); break; case 2: purple_connection_update_progress(gc, "Waiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connected", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; break; default: break; }; char * msg, * who, * prev, * url, *author; int status; int size; double lat,lng; // Incoming messages while (waAPI_querychat(wconn->waAPI, &who, &msg, &author)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who,msg); if (isgroup(who)) { // Search fot the combo PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { hasht = purple_chat_get_components(ch); if (strcmp(g_hash_table_lookup(hasht, "id"),who) == 0) { break; } } } node = purple_blist_node_next(node,FALSE); } int convo_id = chatid_to_convo(who); PurpleConversation *convo = purple_find_chat(gc, convo_id); // Create a window if it's not open yet if (!convo) waprpl_chat_join(gc,hasht); if (convo != NULL) { serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), author, PURPLE_MESSAGE_RECV, msg, time(NULL)); }else{ printf("Received group message but could not find the group! %s\n",msg); } }else{ // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, msg, PURPLE_MESSAGE_RECV, time(NULL)); } } while (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url)) { printf("Got chat image %s %s\n",who,url); purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a>",url,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who,(float)lat,(float)lng); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>",lat,lng,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatsound(wconn->waAPI, &who, &url)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\">%s</a>",url,url), PURPLE_MESSAGE_RECV , time(NULL)); } // User status change while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message","", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message","", NULL); } } // User typing info notify while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { serv_got_typing(gc,who,0,PURPLE_TYPING); } else { serv_got_typing_stopped(gc,who); } } // User profile picture char * icon, * hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc,who, g_memdup(icon,len),len, hash); } // Groups update if (waAPI_getgroupsupdated(wconn->waAPI)) { // Delete/update the chats that are in our list PurpleBlistNode* node = purple_blist_get_root(); while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { int found = 0; GHashTable *hasht = purple_chat_get_components(ch); char * grid = g_hash_table_lookup(hasht, "id"); char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { if (strcmp(*gplist,grid) == 0) { // The group is in the system, update the fields char *id,*sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); found = 1; break; } gplist++; } // The group was deleted if (!found) { PurpleBlistNode* del = node; node = purple_blist_node_next(node,FALSE); purple_blist_remove_chat(del); } } } node = purple_blist_node_next(node,FALSE); } // Add new groups char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { int found = 0; PurpleBlistNode* node = purple_blist_get_root(); PurpleChat * ch; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { char * grid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (strcmp(*gplist,grid) == 0) { found = 1; break; } } } node = purple_blist_node_next(node,FALSE); } if (!found) { char *sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", *gplist,sub); GHashTable * htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(*gplist)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc,sub,htable); purple_blist_add_chat(ch,NULL,NULL); } // Now update the open conversation that may exist char * id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation * conv = purple_find_chat(gc, prplid); if (conv) { char *subject, *owner, *part; if (!waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) return; purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); gchar **plist = g_strsplit(part,",",0); while (*plist) { purple_conv_chat_add_user (purple_conversation_get_chat_data(conv), *plist,"",PURPLE_CBFLAGS_NONE | (!strcmp(owner,*plist) ? PURPLE_CBFLAGS_FOUNDER : 0),FALSE); plist++; } } gplist++; } } }
/** * purplemot_login - Login for an account. Establishes a connection * to the discovery server and initializes * * @param acct The account to be logged in */ static void purplemot_login(PurpleAccount *acct) { char **userparts; struct pm_account *account; int port; const char *username = purple_account_get_username(acct); PurpleConnection *gc = purple_account_get_connection(acct); GList *offline_messages; purple_debug_info("purplemot", "logging in %s\n", acct->username); // TODO(carl): initialize motmot here? if (strpbrk(username, " \t\v\r\n") != NULL) { purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Motmot server may not contain whitespace")); return; } gc->proto_data = account = g_new0(struct pm_account, 1); account->pa = acct; userparts = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userparts[0]); account->server_host = g_strdup(userparts[1]); g_strfreev(userparts); port = purple_account_get_int(acct, "disc_port", DEFAULT_PORT); purple_connection_update_progress(gc, _("Connecting"), 0, /* which connection step this is */ 2); /* total number of steps */ purple_debug_info("motmot", "connecting to discovery server"); rpc_connect(account); purple_connection_update_progress(gc, _("Connected"), 1, /* which connection step this is */ 2); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTED); /* fetch stored offline messages */ purple_debug_info("purplemot", "checking for offline messages for %s\n", acct->username); offline_messages = g_hash_table_lookup(goffline_messages, acct->username); while (offline_messages) { GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; purple_debug_info("purplemot", "delivering offline message to %s: %s\n", acct->username, message->message); serv_got_im(gc, message->from, message->message, message->flags, message->mtime); offline_messages = g_list_next(offline_messages); g_free(message->from); g_free(message->message); g_free(message); } g_list_free(offline_messages); g_hash_table_remove(goffline_messages, &acct->username); }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); int err; do { char * reason; err = waAPI_geterror(wconn->waAPI, &reason); if (err != 0) { PurpleConnectionError errcode = PURPLE_CONNECTION_ERROR_OTHER_ERROR; if (err == 1) errcode = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED; purple_connection_error_reason(gc, errcode, reason); g_free(reason); } } while (err != 0); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: if (!wconn->connected) { purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_insert_contacts(gc); waprpl_set_status(account, status); wconn->connected = 1; } break; default: break; }; /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { purple_debug_info(WHATSAPP_ID, "Receiving update information from my groups\n"); /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_replace(hasht, g_strdup("subject"), sub); g_hash_table_replace(hasht, g_strdup("owner"), own); purple_blist_alias_chat(ch, sub); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); g_free(glist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) ch = create_chat_group(gpid, wconn, acc); /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) { conv_add_participants(conv, part, owner); } } g_strfreev(gplist); g_free(glist); } t_message m; while (waAPI_querymsg(wconn->waAPI, &m)) { switch (m.type) { case 0: purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", m.who, m.message); conv_add_message(gc, m.who, m.message, m.author, m.t); break; case 1: { purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", m.who, m.message); int imgid = purple_imgstore_add_with_id(g_memdup(m.image, m.imagelen), m.imagelen, NULL); char *msg = g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a><br/><a href=\"%s\">%s</a>", m.url, imgid, m.url, m.url); conv_add_message(gc, m.who, msg, m.author, m.t); g_free(msg); } break; case 2: { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", m.who, (float)m.lat, (float)m.lng); char * lat = dbl2str(m.lat); char * lng = dbl2str(m.lng); char *msg = g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%s&lon=%s&zoom=20\">" "http://openstreetmap.org/?lat=%s&lon=%s&zoom=20</a>", lat, lng, lat, lng); conv_add_message(gc, m.who, msg, m.author, m.t); g_free(msg); g_free(lng); g_free(lat); } break; case 3: { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", m.who, m.url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", m.url, m.url); conv_add_message(gc, m.who, msg, m.author, m.t); g_free(msg); } break; case 4: { purple_debug_info(WHATSAPP_ID, "Got chat video from %s: %s\n", m.who, m.url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", m.url, m.url); conv_add_message(gc, m.who, msg, m.author, m.t); g_free(msg); } break; case 5: { purple_debug_info(WHATSAPP_ID, "Got phone call from %s\n", m.who); conv_add_message(gc, m.who, "[Trying to voice-call you]", m.author, m.t); } break; default: purple_debug_info(WHATSAPP_ID, "Got an unrecognized message!\n"); break; }; g_free(m.who); g_free(m.author); g_free(m.message); } while (1) { int typer; char msgid[128]; if (!waAPI_queryreceivedmsg(wconn->waAPI, msgid, &typer)) break; purple_debug_info(WHATSAPP_ID, "Received message %s type: %d\n", msgid, typer); purple_signal_emit(purple_connection_get_prpl(gc), "whatsapp-message-received", gc, msgid, typer); } /* Status changes, typing notices and profile pictures. */ query_status(gc); query_typing(gc); query_icon(gc); }
static void skypeweb_login_got_pie(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebAccount *sa = user_data; PurpleAccount *account = sa->account; gchar *pie; gchar *etm; const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST;// "/login?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; GString *postdata; gchar *request; struct timeval tv; struct timezone tz; guint tzhours, tzminutes; if (error_message && *error_message) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); return; } gettimeofday(&tv, &tz); (void) tv; tzminutes = tz.tz_minuteswest; if (tzminutes < 0) tzminutes = -tzminutes; tzhours = tzminutes / 60; tzminutes -= tzhours * 60; pie = skypeweb_string_get_chunk(url_text, len, "=\"pie\" value=\"", "\""); if (!pie) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting PIE value")); return; } etm = skypeweb_string_get_chunk(url_text, len, "=\"etm\" value=\"", "\""); if (!etm) { purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting ETM value")); return; } postdata = g_string_new(""); g_string_append_printf(postdata, "username=%s&", purple_url_encode(purple_account_get_username(account))); g_string_append_printf(postdata, "password=%s&", purple_url_encode(purple_account_get_password(account))); g_string_append_printf(postdata, "timezone_field=%c|%d|%d&", (tz.tz_minuteswest < 0 ? '+' : '-'), tzhours, tzminutes); g_string_append_printf(postdata, "pie=%s&", purple_url_encode(pie)); g_string_append_printf(postdata, "etm=%s&", purple_url_encode(etm)); g_string_append_printf(postdata, "js_time=%" G_GINT64_FORMAT "&", skypeweb_get_js_time()); g_string_append(postdata, "client_id=578134&"); g_string_append(postdata, "redirect_uri=https://web.skype.com/"); request = g_strdup_printf("POST /login?client_id=578134&redirect_uri=https%%3A%%2F%%2Fweb.skype.com HTTP/1.0\r\n" "Connection: close\r\n" "Accept: */*\r\n" "BehaviorOverride: redirectAs404\r\n" "Host: " SKYPEWEB_LOGIN_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", strlen(postdata->str), postdata->str); purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, request, TRUE, 524288, skypeweb_login_did_auth, sa); g_string_free(postdata, TRUE); g_free(request); g_free(pie); g_free(etm); purple_connection_update_progress(sa->pc, _("Authenticating"), 2, 4); }
/* Packet parsers */ int hon_parse_packet(PurpleConnection *gc, gchar* buffer,int packet_length){ GString* hexdump; hon_account *hon = gc->proto_data; guint16 packet_id = read_guint16(buffer); hon->gotPacket = TRUE; #if _DEBUG hexdump = g_string_new(NULL); hexdump_g_string_append(hexdump,"",buffer,packet_length - 2); purple_debug_info(HON_DEBUG_PREFIX, "packet:\nid:%X(%d)\nlength:%d\ndata:\n%s\n",packet_id,packet_id,packet_length, hexdump->str); g_string_free(hexdump,TRUE); #endif switch (packet_id) { case 0: return 0; case HON_SC_AUTH_ACCEPTED/*0x1C00*/: /* logged on ! */ purple_connection_update_progress(gc, _("Connected"), 3, /* which connection step this is */ 4); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTED); break; case HON_SC_PING/*0x01*/: hon_send_pong(gc); purple_debug_info(HON_DEBUG_PREFIX, "server ping, sending pong\n"); break; case HON_SC_CHANNEL_MSG/*0x03*/: hon_parse_chat_message(gc,buffer); break; case HON_SC_CHANGED_CHANNEL/*0x04*/: hon_parse_chat_entering(gc,buffer); break; case HON_SC_JOINED_CHANNEL/*0x05*/: hon_parse_chat_join(gc,buffer); break; case HON_SC_LEFT_CHANNEL/*0x06*/: hon_parse_chat_leave(gc,buffer); break; case HON_SC_WHISPER/*0x08*/: hon_parse_pm_whisper(gc,buffer,TRUE); break; case HON_SC_WHISPER_FAILED/*0x09*/: hon_parse_whisper_failed(gc,buffer); break; case HON_SC_INITIAL_STATUS/*0x0B*/: hon_parse_initiall_statuses(gc,buffer); break; case HON_SC_UPDATE_STATUS/*0x0C*/: hon_parse_user_status(gc,buffer); break; case HON_SC_CLAN_MESSAGE/*0x13*/: hon_parse_clan_message(gc,buffer); break; case HON_SC_PM/*0x1C*/: hon_parse_pm_whisper(gc,buffer,FALSE); break; case HON_SC_PM_FAILED/*0x1D*/: hon_parse_pm_failed(gc,buffer); break; case HON_SC_WHISPER_BUDDIES/*0x20*/: hon_parse_pm_whisper(gc,buffer,3); break; case HON_SC_MAX_CHANNELS/*0x21*/: hon_parse_max_channels(gc,buffer); break; case HON_SC_USER_INFO_NO_EXIST/*0x2b*/: case HON_SC_USER_INFO_OFFLINE/*0x2c*/: case HON_SC_USER_INFO_ONLINE/*0x2d*/: case HON_SC_USER_INFO_IN_GAME/*0x2e*/: hon_parse_userinfo(gc,buffer,packet_id); break; case HON_SC_CHANNEL_UPDATE: hon_parse_channel_update(gc,buffer); break; case HON_SC_UPDATE_TOPIC/*0x30*/: hon_parse_chat_topic(gc,buffer); break; case HON_SC_CHANNEL_KICK/*0x31*/: hon_parse_channel_kick(gc,buffer); break; case HON_SC_CHANNEL_BAN/*0x32*/: case HON_SC_CHANNEL_UNBAN/*0x33*/: hon_parse_channel_ban_unban(gc,buffer,packet_id); break; case HON_SC_CHANNEL_BANNED/*0x34*/: hon_parse_channel_banned(gc,buffer); break; case HON_SC_CHANNEL_SILENCED/*0x35*/: hon_parse_channel_silenced(gc,buffer); break; case HON_SC_CHANNEL_SILENCE_LIFTED/*0x36*/: hon_parse_channel_silence_lifted(gc,buffer); break; case HON_SC_CHANNEL_SILENCE_PLACED/*0x37*/: hon_parse_channel_silence_placed(gc,buffer); break; case HON_SC_CHANNEL_PROMOTE/*0x3A*/: case HON_SC_CHANNEL_DEMOTE/*0x3A*/: hon_parse_channel_promote_demote(gc,buffer,packet_id); break; case HON_SC_MESSAGE_ALL/*0x39*/: hon_parse_global_notification(gc,buffer); break; case HON_SC_CHANNEL_AUTH_ENABLE: case HON_SC_CHANNEL_AUTH_DISABLE: hon_parse_channel_auth_enable_disable(gc,buffer,packet_id); break; case HON_SC_CHANNEL_AUTH_ADD: case HON_SC_CHANNEL_AUTH_DELETE: case HON_SC_CHANNEL_ADD_AUTH_FAIL: case HON_SC_CHANNEL_DEL_AUTH_FAIL: hon_parse_channel_auth_add_delete(gc,buffer,packet_id); break; case HON_SC_CHANNEL_AUTH_LIST: hon_parse_channel_auth_list(gc,buffer); break; case HON_SC_CHANNEL_PASSWORD_CHANGED/*0x43*/: hon_parse_channel_password_changed(gc,buffer); break; case HON_SC_JOIN_CHANNEL_PASSWORD/*0x46*/: hon_parse_join_channel_password(gc,buffer); break; case HON_SC_CHANNEL_EMOTE/*0x65*/: case HON_SC_CHANNEL_ROLL/*0x64*/: hon_parse_emote_roll(gc,buffer,packet_id); break; case 0x18: read_string(buffer); break; case HON_SC_TOTAL_ONLINE: //read_guint32(buffer); packet_length = read_guint32(buffer); purple_debug_info(HON_DEBUG_PREFIX, "total online : %d\n",packet_length); break; case HON_SC_REQUEST_NOTIFICATION/*0xB2*/: hon_parse_request(gc,buffer); break; case HON_SC_NOTIFICATION/*0xB4*/: hon_parse_notification(gc,buffer); break; case HON_SC_TMM_INVITE/*0xC0D*/: hon_parse_tmm_invite(gc,buffer); break; default: hexdump = g_string_new(NULL); hexdump_g_string_append(hexdump,"",(guint8*)buffer,packet_length - sizeof(packet_id)); purple_debug_info(HON_DEBUG_PREFIX, "unknown packet:\nid:%X(%d)\nlength:%d\ndata:\n%s\n",packet_id,packet_id,packet_length, hexdump->str); g_string_free(hexdump,TRUE); break; } return 1; }
guint8 qq_proc_login_cmds(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len, guint32 update_class, guintptr ship_value) { qq_data *qd; guint8 *data = NULL; gint data_len = 0; guint ret_8 = QQ_LOGIN_REPLY_ERR; g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); qd = (qq_data *) gc->proto_data; g_return_val_if_fail(rcved_len > 0, QQ_LOGIN_REPLY_ERR); data = g_newa(guint8, rcved_len); switch (cmd) { case QQ_CMD_TOUCH_SERVER: case QQ_CMD_CAPTCHA: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.random_key); break; case QQ_CMD_AUTH: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.random_key); if (data_len >= 0) { purple_debug_warning("QQ", "Decrypt login packet by random_key, %d bytes\n", data_len); } else { data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[4]); if (data_len >= 0) { purple_debug_warning("QQ", "Decrypt login packet by auth_key1, %d bytes\n", data_len); } } break; case QQ_CMD_VERIFY_DE: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[0]); break; case QQ_CMD_VERIFY_E5: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[1]); break; case QQ_CMD_VERIFY_E3: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[3]); break; case QQ_CMD_LOGIN: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[2]); if (data_len >= 0) { purple_debug_info("QQ", "Decrypt login packet by Key0_VerifyE5\n"); } else { /* network condition may has changed. please sign in again. */ data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[0]); if (data_len >= 0) { purple_debug_info("QQ", "Decrypt login packet rarely by Key2_Auth\n"); } } break; case QQ_CMD_LOGIN_E9: case QQ_CMD_LOGIN_EA: case QQ_CMD_LOGIN_GETLIST: case QQ_CMD_LOGIN_ED: case QQ_CMD_LOGIN_EC: default: data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); break; } if (data_len < 0) { purple_debug_warning("QQ", "Can not decrypt login cmd, [%05d], 0x%04X %s, len %d\n", seq, cmd, qq_get_cmd_desc(cmd), rcved_len); qq_show_packet("Can not decrypted", rcved, rcved_len); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Unable to decrypt login reply")); return QQ_LOGIN_REPLY_ERR; } switch (cmd) { case QQ_CMD_TOUCH_SERVER: ret_8 = qq_process_touch_server(gc, data, data_len); if ( ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_captcha(gc); } else if ( ret_8 == QQ_TOUCH_REPLY_REDIRECT) { return QQ_TOUCH_REPLY_REDIRECT; } break; case QQ_CMD_CAPTCHA: ret_8 = qq_process_captcha(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_auth(gc); } else if (ret_8 == QQ_LOGIN_REPLY_NEXT_CAPTCHA) { qq_request_captcha_next(gc); } else if (ret_8 == QQ_LOGIN_REPLY_CAPTCHA_DLG) { qq_captcha_input_dialog(gc, &(qd->captcha)); g_free(qd->captcha.token); g_free(qd->captcha.data); memset(&qd->captcha, 0, sizeof(qd->captcha)); } break; case QQ_CMD_AUTH: ret_8 = qq_process_auth(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_DE) { qq_request_verify_DE(gc); } else if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_verify_E5(gc); } else return ret_8; break; case QQ_CMD_VERIFY_DE: ret_8 = qq_process_verify_DE(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_verify_E5(gc); break; case QQ_CMD_VERIFY_E5: ret_8 = qq_process_verify_E5(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_verify_E3(gc); break; case QQ_CMD_VERIFY_E3: ret_8 = qq_process_verify_E3(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_login(gc); break; case QQ_CMD_LOGIN: ret_8 = qq_process_login(gc, data, data_len); if ( ret_8 == QQ_TOUCH_REPLY_REDIRECT) { qq_request_touch_server(gc); return QQ_LOGIN_REPLY_OK; } if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_login_E9(gc); } else { return ret_8; } break; case QQ_CMD_LOGIN_E9: qq_request_login_EA(gc); break; case QQ_CMD_LOGIN_EA: qq_request_login_getlist(gc, 0x0001); break; case QQ_CMD_LOGIN_GETLIST: ret_8 = qq_process_login_getlist(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_login_ED(gc); } break; case QQ_CMD_LOGIN_EC: break; case QQ_CMD_LOGIN_ED: qq_request_login_EC(gc); purple_connection_update_progress(gc, _("Logging in"), QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS); purple_debug_info("QQ", "Login replies OK; everything is fine\n"); purple_connection_set_state(gc, PURPLE_CONNECTED); qd->is_login = TRUE; /* must be defined after sev_finish_login */ /* is_login, but we have packets before login */ qq_trans_process_remained(gc); qq_update_all(gc, 0); break; default: process_unknown_cmd(gc, _("Unknown LOGIN CMD"), data, data_len, cmd, seq); return QQ_LOGIN_REPLY_ERR; } return QQ_LOGIN_REPLY_OK; }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_replace(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_replace(hasht, g_strdup("owner"), g_strdup(own)); purple_blist_alias_chat(ch, g_strdup(sub)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } /* Incoming messages. */ for (;;) { int r = waAPI_querynext(wconn->waAPI); if (r < 0) break; switch (r) { case 0: query_chat_message(gc); break; case 1: query_chat_image(gc); break; case 2: query_chat_location(gc); break; case 3: query_chat_sound(gc); break; case 4: query_chat_video(gc); break; default: /* Unsupported message type. */ break; }; } /* Status changes, typing notices and profile pictures. */ query_status(gc); query_typing(gc); query_icon(gc); }