コード例 #1
0
ファイル: qq_network.c プロジェクト: cysfek/openq-ng
/* 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);
}
コード例 #2
0
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);
    
}
コード例 #3
0
ファイル: login.c プロジェクト: Distrotech/pidgin
/*------------------------------------------------------------------------
 * 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 );
	}
}
コード例 #4
0
ファイル: openfetion.c プロジェクト: amoblin/flyshion
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);
}
コード例 #5
0
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);
}
コード例 #6
0
ファイル: qq_network.c プロジェクト: cysfek/openq-ng
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;
}
コード例 #7
0
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"));
*/
}
コード例 #8
0
ファイル: irc.c プロジェクト: arminius2/apolloim
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;
		}
	}
}
コード例 #9
0
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);
}
コード例 #10
0
ファイル: nullprpl.c プロジェクト: Distrotech/pidgin
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));
}
コード例 #11
0
ファイル: login.c プロジェクト: Distrotech/pidgin
/*------------------------------------------------------------------------
 * 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 );
	}
}
コード例 #12
0
ファイル: napster.c プロジェクト: rgenoud/purple-plugin-pack
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."));
    }
}
コード例 #13
0
ファイル: wa_purple.c プロジェクト: jab15pm/whatsapp-purple
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);
	}
}
コード例 #14
0
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);
}
コード例 #15
0
ファイル: session.c プロジェクト: N8Fear/purple-facebook
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);
}
コード例 #16
0
ファイル: napster.c プロジェクト: rgenoud/purple-plugin-pack
/* 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);
}
コード例 #17
0
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);
}
コード例 #18
0
ファイル: plainprpl.c プロジェクト: mwarning/plain-prpl
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);
}
コード例 #19
0
ファイル: wa_purple.c プロジェクト: sanaewah/whatsapp-purple
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, &timestamp)) {
			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, &timestamp)) {
			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, &timestamp)) {
			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, &timestamp)) {
			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);
	}
}
コード例 #20
0
ファイル: f_login.c プロジェクト: xanadulama/fetion
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);

}
コード例 #21
0
ファイル: util.c プロジェクト: Draghtnod/pidgin
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;
}
コード例 #22
0
ファイル: skypeweb_login.c プロジェクト: kenvac/skype4pidgin
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);
}
コード例 #23
0
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);
}
コード例 #24
0
ファイル: wa_purple.c プロジェクト: yah0o2010/whatsapp-purple
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++;
    }
  }
}
コード例 #25
0
ファイル: purplemot.c プロジェクト: flowerhack/motmot
/**
 * 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);
}
コード例 #26
0
ファイル: wa_purple.c プロジェクト: jab15pm/whatsapp-purple
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);
}
コード例 #27
0
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);
}
コード例 #28
0
ファイル: hon.c プロジェクト: theli-ua/honpurple
/* 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;
}
コード例 #29
0
ファイル: qq_process.c プロジェクト: 1dot75cm/pidgin-libqq
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;
}
コード例 #30
0
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);
}