Example #1
0
/*------------------------------------------------------------------------
 * Enable the user to change their PIN.
 *
 *  @param action	The action object
 */
static void mxit_change_pin_action( PurplePluginAction* action )
{
	PurpleConnection*			gc		= (PurpleConnection*) action->context;

	PurpleRequestFields*		fields	= NULL;
	PurpleRequestFieldGroup*	group	= NULL;
	PurpleRequestField*			field	= NULL;

	purple_debug_info( MXIT_PLUGIN_ID, "mxit_change_pin_action\n" );

	fields = purple_request_fields_new();
	group = purple_request_field_group_new( NULL );
	purple_request_fields_add_group( fields, group );

	/* pin */
	field = purple_request_field_string_new( "pin", _( "PIN" ), purple_connection_get_password( gc ), FALSE );
	purple_request_field_string_set_masked( field, TRUE );
	purple_request_field_group_add_field( group, field );

	/* verify pin */
	field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), purple_connection_get_password( gc ), FALSE );
	purple_request_field_string_set_masked( field, TRUE );
	purple_request_field_group_add_field( group, field );

	/* (reference: "libpurple/request.h") */
	purple_request_fields( gc, _( "Change PIN" ), _( "Change MXit PIN" ), NULL, fields, _( "Set" ),
			G_CALLBACK( mxit_change_pin_cb ), _( "Cancel" ), NULL, purple_request_cpar_from_connection(gc), gc );
}
Example #2
0
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);
}
Example #3
0
void jabber_auth_start_old(JabberStream *js)
{
	PurpleAccount *account;
	JabberIq *iq;
	PurpleXmlNode *query, *username;

	account = purple_connection_get_account(js->gc);

	/*
	 * We can end up here without encryption if the server doesn't support
	 * <stream:features/> and we're not using old-style SSL.  If the user
	 * is requiring SSL/TLS, we need to enforce it.
	 */
	if (!jabber_stream_is_ssl(js) &&
			g_str_equal("require_tls",
				purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
		purple_connection_error(js->gc,
			PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
			_("You require encryption, but it is not available on this server."));
		return;
	}

	if (js->registration) {
		jabber_register_start(js);
		return;
	}

	/*
	 * IQ Auth doesn't have support for resource binding, so we need to pick a
	 * default resource so it will work properly.  jabberd14 throws an error and
	 * iChat server just fails silently.
	 */
	if (!js->user->resource || *js->user->resource == '\0') {
		g_free(js->user->resource);
		js->user->resource = g_strdup("Home");
	}

#ifdef HAVE_CYRUS_SASL
	/* If we have Cyrus SASL, then passwords will have been set
	 * to OPTIONAL for this protocol. So, we need to do our own
	 * password prompting here
	 */

	if (!purple_connection_get_password(js->gc)) {
		purple_account_request_password(account, G_CALLBACK(auth_old_pass_cb), G_CALLBACK(auth_no_pass_cb), js->gc);
		return;
	}
#endif
	iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:auth");

	query = purple_xmlnode_get_child(iq->node, "query");
	username = purple_xmlnode_new_child(query, "username");
	purple_xmlnode_insert_data(username, js->user->node, -1);

	jabber_iq_set_callback(iq, auth_old_cb, NULL);

	jabber_iq_send(iq);
}
Example #4
0
static void client_login_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
{
    OscarData *od;
    PurpleConnection *gc;
    char *token, *secret, *session_key;
    time_t hosttime;
    int password_len;
    char *password;

    od = user_data;
    gc = od->gc;

    od->url_data = NULL;

    if (error_message != NULL || len == 0) {
        gchar *tmp;
        if (error_message != NULL)
            tmp = g_strdup_printf(_("Error requesting %s: %s"),
                                  URL_CLIENT_LOGIN, error_message);
        else
            tmp = g_strdup_printf(_("Error requesting %s"),
                                  URL_CLIENT_LOGIN);
        purple_connection_error_reason(gc,
                                       PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
        g_free(tmp);
        return;
    }

    if (!parse_client_login_response(gc, url_text, len, &token, &secret, &hosttime))
        return;

    password_len = strlen(purple_connection_get_password(gc));
    password = g_strdup_printf("%.*s",
                               od->icq ? MIN(password_len, MAXICQPASSLEN) : password_len,
                               purple_connection_get_password(gc));
    session_key = hmac_sha256(password, secret);
    g_free(password);
    g_free(secret);

    send_start_oscar_session(od, token, session_key, hosttime);

    g_free(token);
    g_free(session_key);
}
Example #5
0
static gboolean do_login(PurpleConnection *gc) {
	char *buf, *tmp = NULL;
	char hostname[256];
	const char *username, *realname;
	struct irc_conn *irc = gc->proto_data;
	const char *pass = purple_connection_get_password(gc);

	if (pass && *pass) {
		buf = irc_format(irc, "vv", "PASS", pass);
		if (irc_send(irc, buf) < 0) {
/*			purple_connection_error(gc, "Error sending password"); */
			g_free(buf);
			return FALSE;
		}
		g_free(buf);
	}


	gethostname(hostname, sizeof(hostname));
	hostname[sizeof(hostname) - 1] = '\0';
	realname = purple_account_get_string(irc->account, "realname", "");
	username = purple_account_get_string(irc->account, "username", "");

	if (username == NULL || *username == '\0') {
		username = g_get_user_name();
	}

	if (username != NULL && strchr(username, ' ') != NULL) {
		tmp = g_strdup(username);
		while ((buf = strchr(tmp, ' ')) != NULL) {
			*buf = '_';
		}
	}

	buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : username, hostname, irc->server,
			      strlen(realname) ? realname : IRC_DEFAULT_ALIAS);
	g_free(tmp);
	if (irc_send(irc, buf) < 0) {
/*		purple_connection_error(gc, "Error registering with server");*/
		g_free(buf);
		return FALSE;
	}
	g_free(buf);
	buf = irc_format(irc, "vn", "NICK", purple_connection_get_display_name(gc));
	if (irc_send(irc, buf) < 0) {
/*		purple_connection_error(gc, "Error sending nickname");*/
		g_free(buf);
		return FALSE;
	}
	g_free(buf);

	irc->recv_time = time(NULL);

	return TRUE;
}
Example #6
0
/**
 * This function sends a request to
 * https://api.screenname.aol.com/auth/clientLogin with the user's
 * username and password and receives the user's session key, which is
 * used to request a connection to the BOSS server.
 */
void send_client_login(OscarData *od, const char *username)
{
    PurpleConnection *gc;
    GString *request, *body;
    const char *tmp;
    char *password;
    int password_len;

    gc = od->gc;

    /*
     * We truncate ICQ passwords to 8 characters.  There is probably a
     * limit for AIM passwords, too, but we really only need to do
     * this for ICQ because older ICQ clients let you enter a password
     * as long as you wanted and then they truncated it silently.
     *
     * And we can truncate based on the number of bytes and not the
     * number of characters because passwords for AIM and ICQ are
     * supposed to be plain ASCII (I don't know if this has always been
     * the case, though).
     */
    tmp = purple_connection_get_password(gc);
    password_len = strlen(tmp);
    password = g_strndup(tmp, od->icq ? MIN(password_len, MAXICQPASSLEN) : password_len);

    /* Construct the body of the HTTP POST request */
    body = g_string_new("");
    g_string_append_printf(body, "devId=%s", get_client_key(od));
    g_string_append_printf(body, "&f=xml");
    g_string_append_printf(body, "&pwd=%s", purple_url_encode(password));
    g_string_append_printf(body, "&s=%s", purple_url_encode(username));
    g_free(password);

    /* Construct an HTTP POST request */
    request = g_string_new("POST /auth/clientLogin HTTP/1.0\r\n"
                           "Connection: close\r\n"
                           "Accept: */*\r\n");

    /* Tack on the body */
    g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n");
    g_string_append_printf(request, "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n", body->len);
    g_string_append_len(request, body->str, body->len);
    g_string_free(body, TRUE);

    /* Send the POST request  */
    od->url_data = purple_util_fetch_url_request_len_with_account(
                       purple_connection_get_account(gc), URL_CLIENT_LOGIN,
                       TRUE, NULL, FALSE, request->str, FALSE, -1,
                       client_login_cb, od);
    g_string_free(request, TRUE);
}
Example #7
0
/*when connect, do the SOAP Style windows Live ID authentication */
void
msn_nexus_connect(MsnNexus *nexus)
{
	MsnSession *session = nexus->session;
	const char *username;
	const char *password;
	char *password_xml;
	GString *domains;
	char *request;
	int i;

	MsnSoapMessage *soap;

	purple_debug_info("msn", "Starting Windows Live ID authentication\n");
	msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);

	username = purple_account_get_username(session->account);
	password = purple_connection_get_password(session->account->gc);
	if (g_utf8_strlen(password, -1) > 16) {
		/* max byte size for 16 utf8 characters is 64 + 1 for the null */
		gchar truncated[65];
		g_utf8_strncpy(truncated, password, 16);
		password_xml = g_markup_escape_text(truncated, -1);
	} else {
		password_xml = g_markup_escape_text(password, -1);
	}

	purple_debug_info("msn", "Logging on %s, with policy '%s', nonce '%s'\n",
	                  username, nexus->policy, nexus->nonce);

	domains = g_string_new(NULL);
	for (i = 0; i < nexus->token_len; i++) {
		g_string_append_printf(domains, MSN_SSO_RST_TEMPLATE,
		                       i+1,
		                       ticket_domains[i][SSO_VALID_TICKET_DOMAIN],
		                       ticket_domains[i][SSO_VALID_TICKET_POLICY] != NULL ?
		                           ticket_domains[i][SSO_VALID_TICKET_POLICY] :
		                           nexus->policy);
	}

	request = g_strdup_printf(MSN_SSO_TEMPLATE, username, password_xml, domains->str);
	g_free(password_xml);
	g_string_free(domains, TRUE);

	soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1));
	g_free(request);
	msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE,
	                      nexus_got_response_cb, nexus);
}
Example #8
0
static void finish_plaintext_authentication(JabberStream *js)
{
	JabberIq *iq;
	PurpleXmlNode *query, *x;

	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
	query = purple_xmlnode_get_child(iq->node, "query");
	x = purple_xmlnode_new_child(query, "username");
	purple_xmlnode_insert_data(x, js->user->node, -1);
	x = purple_xmlnode_new_child(query, "resource");
	purple_xmlnode_insert_data(x, js->user->resource, -1);
	x = purple_xmlnode_new_child(query, "password");
	purple_xmlnode_insert_data(x, purple_connection_get_password(js->gc), -1);
	jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
	jabber_iq_send(iq);
}
Example #9
0
void twitter_send_request(PurpleAccount *account, gboolean post,
		const char *url, const char *query_string, 
		TwitterSendRequestSuccessFunc success_callback, TwitterSendRequestErrorFunc error_callback,
		gpointer data)
{
	gchar *request;
	const char *pass = purple_connection_get_password(purple_account_get_connection(account));
	const char *sn = purple_account_get_username(account);
	char *auth_text = g_strdup_printf("%s:%s", sn, pass);
	char *auth_text_b64 = purple_base64_encode((guchar *) auth_text, strlen(auth_text));
	gboolean use_https = purple_account_get_bool(account, "use_https", FALSE) && purple_ssl_is_supported();
	char *host = "twitter.com";
	TwitterSendRequestData *request_data = g_new0(TwitterSendRequestData, 1);
	char *full_url = g_strdup_printf("%s://%s%s",
			use_https ? "https" : "http",
			host,
			url);
	request_data->account = account;
	request_data->user_data = data;
	request_data->success_func = success_callback;
	request_data->error_func = error_callback;

	g_free(auth_text);

	request = g_strdup_printf(
			"%s %s%s%s HTTP/1.0\r\n"
			"User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
			"Host: %s\r\n"
			"Authorization: Basic %s\r\n"
			"Content-Length: %d\r\n\r\n"
			"%s",
			post ? "POST" : "GET",
			full_url,
			(!post && query_string ? "?" : ""), (!post && query_string ? query_string : ""),
			host,
			auth_text_b64,
			query_string  && post ? strlen(query_string) : 0,
			query_string && post ? query_string : "");

	g_free(auth_text_b64);
	purple_util_fetch_url_request(full_url, TRUE,
			"Mozilla/4.0 (compatible; MSIE 5.5)", TRUE, request, FALSE,
			twitter_send_request_cb, request_data);
	g_free(full_url);
	g_free(request);
}
Example #10
0
/*------------------------------------------------------------------------
 * Generate the Transport-Layer crypto key.
 *  (Note: this function is not-thread safe)
 *
 *  @param session	The MXit Session object
 *	@return			The transport-layer crypto key.
 */
static char* transport_layer_key( struct MXitSession* session )
{
	static char	key[16 + 1];
	const char*	password		= purple_connection_get_password( session->con );
	int			passlen			= strlen( password );

	/* initialize with initial key */
	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );

	/* client key (8 bytes) */
	memcpy( key, session->clientkey, strlen( session->clientkey ) );

	/* add last 8 characters of the PIN (no padding if less characters) */
	if ( passlen <= 8 )
		memcpy( key + 8, password, passlen );
	else
		memcpy( key + 8, password + ( passlen - 8 ), 8 );

	return key;
}
Example #11
0
/*------------------------------------------------------------------------
 * Encrypt the user's cleartext password using the AES 128-bit (ECB)
 *  encryption algorithm.
 *
 *  @param session	The MXit session object
 *  @return			The encrypted & encoded password.  Must be g_free'd when no longer needed.
 */
char* mxit_encrypt_password( struct MXitSession* session )
{
	char			key[16 + 1];
	char			exkey[512];
	GString*		pass			= NULL;
	GString*		encrypted		= NULL;
	char*			base64;
	unsigned int	i;

	purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );

	/* build the AES encryption key */
	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
	memcpy( key, session->clientkey, strlen( session->clientkey ) );
	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );

	/* build the secret data to be encrypted: SECRET_HEADER + password */
	pass = g_string_new( SECRET_HEADER );
	g_string_append( pass, purple_connection_get_password( session->con ) );
	padding_add( pass );		/* add ISO10126 padding */

	/* now encrypt the secret. we encrypt each block separately (ECB mode) */
	encrypted = g_string_sized_new( pass->len );
	for ( i = 0; i < pass->len; i += 16 ) {
		char	block[16];

		Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) block );
		g_string_append_len( encrypted, block, 16 );
	}

	/* now base64 encode the encrypted password */
	base64 = purple_base64_encode( (unsigned char*) encrypted->str, encrypted->len );
	g_string_free( encrypted, TRUE );

	g_string_free( pass, TRUE );

	return base64;
}
Example #12
0
/* 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);
}
Example #13
0
static void
url_cmd (MsnCmdProc *cmdproc,
         MsnCommand *cmd)
{
    MsnSession *session;
    PurpleConnection *connection;
    const gchar *rru;
    const gchar *url;
    gchar creds[64];
    glong tmp_timestamp;

    session = cmdproc->session;
    connection = purple_account_get_connection (session->account);

    rru = cmd->params[1];
    url = cmd->params[2];

    session->passport_info.mail_url_timestamp = time (NULL);
    tmp_timestamp = session->passport_info.mail_url_timestamp - session->passport_info.sl;

    {
        PurpleCipher *cipher;
        PurpleCipherContext *context;
        guchar digest[16];
        gchar *buf;

        buf = pecan_strdup_printf ("%s%ld%s",
                                   session->passport_info.mspauth ? session->passport_info.mspauth : "BOGUS",
                                   tmp_timestamp,
                                   purple_connection_get_password (connection));

        cipher = purple_ciphers_find_cipher ("md5");
        context = purple_cipher_context_new (cipher, NULL);

        purple_cipher_context_append (context, (const guchar *) buf, strlen (buf));
        purple_cipher_context_digest (context, sizeof (digest), digest, NULL);
        purple_cipher_context_destroy (context);

        g_free (buf);

        memset (creds, 0, sizeof (creds));

        {
            gchar buf2[3];
            gint i;

            for (i = 0; i < 16; i++)
            {
                g_snprintf (buf2, sizeof (buf2), "%02x", digest[i]);
                strcat (creds, buf2);
            }
        }
    }

    g_free (session->passport_info.mail_url);

    session->passport_info.mail_url = g_strdup_printf ("%s&auth=%s&creds=%s&sl=%ld&username=%s&mode=ttl&sid=%s&id=2&rru=%ssvc_mail&js=yes",
                                                       url,
                                                       session->passport_info.mspauth,
                                                       creds,
                                                       tmp_timestamp,
                                                       msn_session_get_username (session),
                                                       session->passport_info.sid,
                                                       rru);

    /* The user wants to check his email */
    if (cmd->trans && cmd->trans->data)
    {
        purple_notify_uri (connection, session->passport_info.mail_url);
        return;
    }

    if (purple_account_get_check_mail (session->account))
    {
        static gboolean is_initial = TRUE;

        if (!is_initial)
            return;

        if (session->inbox_unread_count > 0)
        {
            const gchar *passport;
            const gchar *main_url;

            passport = msn_session_get_username (session);
            main_url = session->passport_info.mail_url;

            purple_notify_emails (connection, session->inbox_unread_count, FALSE, NULL, NULL,
                                  &passport, &main_url, NULL, NULL);
        }

        is_initial = FALSE;
    }
}
Example #14
0
File: irc.c Project: dylex/pidgin
static gboolean do_login(PurpleConnection *gc) {
	char *buf, *tmp = NULL;
	char *server;
	const char *nickname, *identname, *realname;
	struct irc_conn *irc = gc->proto_data;
	const char *pass = purple_connection_get_password(gc);
#ifdef HAVE_CYRUS_SASL
	const gboolean use_sasl = purple_account_get_bool(irc->account, "sasl", FALSE);
#endif

	if (pass && *pass) {
#ifdef HAVE_CYRUS_SASL
		if (use_sasl)
			buf = irc_format(irc, "vv:", "CAP", "REQ", "sasl");
		else /* intended to fall through */
#endif
			buf = irc_format(irc, "v:", "PASS", pass);
		if (irc_send(irc, buf) < 0) {
			g_free(buf);
			return FALSE;
		}
		g_free(buf);
	}

	realname = purple_account_get_string(irc->account, "realname", "");
	identname = purple_account_get_string(irc->account, "username", "");

	if (identname == NULL || *identname == '\0') {
		identname = g_get_user_name();
	}

	if (identname != NULL && strchr(identname, ' ') != NULL) {
		tmp = g_strdup(identname);
		while ((buf = strchr(tmp, ' ')) != NULL) {
			*buf = '_';
		}
	}

	if (*irc->server == ':') {
		/* Same as hostname, above. */
		server = g_strdup_printf("0%s", irc->server);
	} else {
		server = g_strdup(irc->server);
	}

	buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : identname, "*", server,
	                 strlen(realname) ? realname : IRC_DEFAULT_ALIAS);
	g_free(tmp);
	g_free(server);
	if (irc_send(irc, buf) < 0) {
		g_free(buf);
		return FALSE;
	}
	g_free(buf);
	nickname = purple_connection_get_display_name(gc);
	buf = irc_format(irc, "vn", "NICK", nickname);
	irc->reqnick = g_strdup(nickname);
	irc->nickused = FALSE;
	if (irc_send(irc, buf) < 0) {
		g_free(buf);
		return FALSE;
	}
	g_free(buf);

	irc->recv_time = time(NULL);

	return TRUE;
}
Example #15
0
static JabberSaslState
scram_start(JabberStream *js, PurpleXmlNode *mechanisms, PurpleXmlNode **out, char **error)
{
	PurpleXmlNode *reply;
	JabberScramData *data;
	guint64 cnonce;
#ifdef CHANNEL_BINDING
	gboolean binding_supported = TRUE;
#endif
	gchar *dec_out, *enc_out;
	gchar *prepped_node, *tmp;
	gchar *prepped_pass;

	prepped_node = jabber_saslprep(js->user->node);
	if (!prepped_node) {
		*error = g_strdup(_("Unable to canonicalize username"));
		return JABBER_SASL_STATE_FAIL;
	}

	tmp = escape_username(prepped_node);
	g_free(prepped_node);
	prepped_node = tmp;

	prepped_pass = jabber_saslprep(purple_connection_get_password(js->gc));
	if (!prepped_pass) {
		g_free(prepped_node);
		*error = g_strdup(_("Unable to canonicalize password"));
		return JABBER_SASL_STATE_FAIL;
	}

	data = js->auth_mech_data = g_new0(JabberScramData, 1);
	data->hash = mech_to_hash(js->auth_mech->name);
	data->password = prepped_pass;

#ifdef CHANNEL_BINDING
	if (strstr(js->auth_mech_name, "-PLUS"))
		data->channel_binding = TRUE;
#endif
	cnonce = ((guint64)g_random_int() << 32) | g_random_int();
	data->cnonce = purple_base64_encode((guchar *)&cnonce, sizeof(cnonce));

	data->auth_message = g_string_new(NULL);
	g_string_printf(data->auth_message, "n=%s,r=%s",
			prepped_node, data->cnonce);
	g_free(prepped_node);

	data->step = 1;

	reply = purple_xmlnode_new("auth");
	purple_xmlnode_set_namespace(reply, NS_XMPP_SASL);
	purple_xmlnode_set_attrib(reply, "mechanism", js->auth_mech->name);

	/* TODO: Channel binding */
	dec_out = g_strdup_printf("%c,,%s", 'n', data->auth_message->str);
	enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out));
	purple_debug_misc("jabber", "initial SCRAM message '%s'\n", dec_out);

	purple_xmlnode_insert_data(reply, enc_out, -1);

	g_free(enc_out);
	g_free(dec_out);

	*out = reply;
	return JABBER_SASL_STATE_CONTINUE;
}
Example #16
0
void
login_connect_cb(gpointer data, PurpleSslConnection *gsc,
				 PurpleInputCondition cond)
{
	MsnNexus *nexus;
	MsnSession *session;
	char *username, *password, *encpass;
	char *request_str, *head, *tail;
	char *buffer = NULL;
	guint32 ctint;

	nexus = data;
	g_return_if_fail(nexus != NULL);

	session = nexus->session;
	g_return_if_fail(session != NULL);

	msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);

	username =
		g_strdup(purple_url_encode(purple_account_get_username(session->account)));

	password = g_utf8_strncpy(g_strdup(purple_connection_get_password(session->account->gc)),
							  purple_connection_get_password(session->account->gc), 16);
	encpass = g_strdup(purple_url_encode(password));
	g_free(password);

	ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200;

	head = g_strdup_printf(
		"GET %s HTTP/1.1\r\n"
		"Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s",
		nexus->login_path,
		(char *)g_hash_table_lookup(nexus->challenge_data, "ru"),
		username);

	tail = g_strdup_printf(
		"lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n"
		"User-Agent: MSMSGS\r\n"
		"Host: %s\r\n"
		"Connection: Keep-Alive\r\n"
		"Cache-Control: no-cache\r\n",
		nexus_challenge_data_lookup(nexus->challenge_data, "lc"),
		nexus_challenge_data_lookup(nexus->challenge_data, "id"),
		nexus_challenge_data_lookup(nexus->challenge_data, "tw"),
		nexus_challenge_data_lookup(nexus->challenge_data, "fs"),
		nexus_challenge_data_lookup(nexus->challenge_data, "ru"),
		ctint,
		nexus_challenge_data_lookup(nexus->challenge_data, "kpp"),
		nexus_challenge_data_lookup(nexus->challenge_data, "kv"),
		nexus_challenge_data_lookup(nexus->challenge_data, "ver"),
		nexus_challenge_data_lookup(nexus->challenge_data, "tpf"),
		nexus->login_host);

	buffer = g_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail);
	request_str = g_strdup_printf("%s,pwd=%s,%s\r\n", head, encpass, tail);

	purple_debug_misc("msn", "Sending: {%s}\n", buffer);

	g_free(buffer);
	g_free(head);
	g_free(tail);
	g_free(username);
	g_free(encpass);

	nexus->write_buf = request_str;
	nexus->written_len = 0;

	nexus->read_len = 0;

	nexus->written_cb = nexus_login_written_cb;

	nexus->input_handler = purple_input_add(gsc->fd, PURPLE_INPUT_WRITE,
		nexus_write_cb, nexus);

	nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE);

	return;


}
static JabberSaslState
digest_md5_handle_challenge(JabberStream *js, PurpleXmlNode *packet,
                            PurpleXmlNode **response, char **msg)
{
	PurpleXmlNode *reply = NULL;
	char *enc_in = purple_xmlnode_get_data(packet);
	char *dec_in;
	char *enc_out;
	GHashTable *parts;
	JabberSaslState state = JABBER_SASL_STATE_CONTINUE;

	if (!enc_in) {
		*msg = g_strdup(_("Invalid response from server"));
		return JABBER_SASL_STATE_FAIL;
	}

	dec_in = (char *)purple_base64_decode(enc_in, NULL);
	purple_debug_misc("jabber", "decoded challenge (%"
			G_GSIZE_FORMAT "): %s\n",
			strlen(dec_in),
			dec_in);

	parts = jabber_auth_digest_md5_parse(dec_in);

	if (g_hash_table_lookup(parts, "rspauth")) {
		char *rspauth = g_hash_table_lookup(parts, "rspauth");
		char *expected_rspauth = js->auth_mech_data;

		if (rspauth && purple_strequal(rspauth, expected_rspauth)) {
			reply = purple_xmlnode_new("response");
			purple_xmlnode_set_namespace(reply, NS_XMPP_SASL);
		} else {
			*msg = g_strdup(_("Invalid challenge from server"));
			state = JABBER_SASL_STATE_FAIL;
		}
		g_free(js->auth_mech_data);
		js->auth_mech_data = NULL;
	} else {
		/* assemble a response, and send it */
		/* see RFC 2831 */
		char *realm;
		char *nonce;

		/* Make sure the auth string contains everything that should be there.
		   This isn't everything in RFC2831, but it is what we need. */

		nonce = g_hash_table_lookup(parts, "nonce");

		/* we're actually supposed to prompt the user for a realm if
		 * the server doesn't send one, but that really complicates things,
		 * so i'm not gonna worry about it until is poses a problem to
		 * someone, or I get really bored */
		realm = g_hash_table_lookup(parts, "realm");
		if(!realm)
			realm = js->user->domain;

		if (nonce == NULL || realm == NULL) {
			*msg = g_strdup(_("Invalid challenge from server"));
			state = JABBER_SASL_STATE_FAIL;
		} else {
			GString *response = g_string_new("");
			char *a2;
			char *auth_resp;
			char *cnonce;

			cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL),
					g_random_int());

			a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm);
			auth_resp = generate_response_value(js->user,
					purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
			g_free(a2);

			a2 = g_strdup_printf(":xmpp/%s", realm);
			js->auth_mech_data = generate_response_value(js->user,
					purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
			g_free(a2);

			g_string_append_printf(response, "username=\"%s\"", js->user->node);
			g_string_append_printf(response, ",realm=\"%s\"", realm);
			g_string_append_printf(response, ",nonce=\"%s\"", nonce);
			g_string_append_printf(response, ",cnonce=\"%s\"", cnonce);
			g_string_append_printf(response, ",nc=00000001");
			g_string_append_printf(response, ",qop=auth");
			g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm);
			g_string_append_printf(response, ",response=%s", auth_resp);
			g_string_append_printf(response, ",charset=utf-8");

			g_free(auth_resp);
			g_free(cnonce);

			enc_out = purple_base64_encode((guchar *)response->str, response->len);

			purple_debug_misc("jabber", "decoded response (%"
					G_GSIZE_FORMAT "): %s\n",
					response->len, response->str);

			reply = purple_xmlnode_new("response");
			purple_xmlnode_set_namespace(reply, NS_XMPP_SASL);
			purple_xmlnode_insert_data(reply, enc_out, -1);

			g_free(enc_out);

			g_string_free(response, TRUE);
		}
	}

	g_free(enc_in);
	g_free(dec_in);
	g_hash_table_destroy(parts);

	*response = reply;
	return state;
}
Example #18
0
static void auth_old_cb(JabberStream *js, const char *from,
                        JabberIqType type, const char *id,
                        PurpleXmlNode *packet, gpointer data)
{
	JabberIq *iq;
	PurpleXmlNode *query, *x;
	const char *pw = purple_connection_get_password(js->gc);

	if (type == JABBER_IQ_ERROR) {
		PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
		char *msg = jabber_parse_error(js, packet, &reason);
		purple_connection_error(js->gc, reason, msg);
		g_free(msg);
	} else if (type == JABBER_IQ_RESULT) {
		query = purple_xmlnode_get_child(packet, "query");
		if (js->stream_id && *js->stream_id &&
				purple_xmlnode_get_child(query, "digest")) {
			char *s, *hash;

			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
			query = purple_xmlnode_get_child(iq->node, "query");
			x = purple_xmlnode_new_child(query, "username");
			purple_xmlnode_insert_data(x, js->user->node, -1);
			x = purple_xmlnode_new_child(query, "resource");
			purple_xmlnode_insert_data(x, js->user->resource, -1);

			x = purple_xmlnode_new_child(query, "digest");
			s = g_strdup_printf("%s%s", js->stream_id, pw);
			hash = jabber_calculate_data_hash(s, strlen(s), "sha1");
			purple_xmlnode_insert_data(x, hash, -1);
			g_free(hash);
			g_free(s);
			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
			jabber_iq_send(iq);
		} else if ((x = purple_xmlnode_get_child(query, "crammd5"))) {
			/* For future reference, this appears to be a custom OS X extension
			 * to non-SASL authentication.
			 */
			const char *challenge;
			gchar digest[33];
			PurpleCipher *hmac;
			PurpleHash *md5;
			gssize diglen;

			/* Calculate the MHAC-MD5 digest */
			md5 = purple_md5_hash_new();
			hmac = purple_hmac_cipher_new(md5);
			challenge = purple_xmlnode_get_attrib(x, "challenge");
			purple_cipher_set_key(hmac, (guchar *)pw, strlen(pw));
			purple_cipher_append(hmac, (guchar *)challenge, strlen(challenge));
			diglen = purple_cipher_digest_to_str(hmac, digest, 33);
			g_object_unref(hmac);
			g_object_unref(md5);

			g_return_if_fail(diglen > 0);

			/* Create the response query */
			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
			query = purple_xmlnode_get_child(iq->node, "query");

			x = purple_xmlnode_new_child(query, "username");
			purple_xmlnode_insert_data(x, js->user->node, -1);
			x = purple_xmlnode_new_child(query, "resource");
			purple_xmlnode_insert_data(x, js->user->resource, -1);

			x = purple_xmlnode_new_child(query, "crammd5");

			purple_xmlnode_insert_data(x, digest, 32);

			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
			jabber_iq_send(iq);

		} else if(purple_xmlnode_get_child(query, "password")) {
			PurpleAccount *account = purple_connection_get_account(js->gc);
			if(!jabber_stream_is_ssl(js) && !purple_account_get_bool(account,
						"auth_plain_in_clear", FALSE)) {
				char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
											purple_account_get_username(account));
				purple_request_yes_no(js->gc, _("Plaintext Authentication"),
						_("Plaintext Authentication"),
						msg,
						1,
						purple_request_cpar_from_account(account),
						account, allow_plaintext_auth,
						disallow_plaintext_auth);
				g_free(msg);
				return;
			}
			finish_plaintext_authentication(js);
		} else {
			purple_connection_error(js->gc,
				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
				_("Server does not use any supported authentication method"));
			return;
		}
	}
}
Example #19
0
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);

}
Example #20
0
static JabberSaslState
fb_handle_challenge(JabberStream *js, xmlnode *packet,
                            xmlnode **response, char **msg)
{
	xmlnode *reply = NULL;
	gchar *challenge;
	guchar *decoded;
	gsize decoded_len;
	gchar **pairs, *method, *nonce;
	gsize i;
	GString *request;
	gchar *enc_out;

	/* Get base64-encoded challenge from XML */
	challenge = xmlnode_get_data(packet);
	if (challenge == NULL) {
		*msg = g_strdup(_("Invalid response from server"));
		return JABBER_SASL_STATE_FAIL;
	}

	/* Decode challenge */
	decoded = purple_base64_decode(challenge, &decoded_len);
	if (decoded == NULL) {
		purple_debug_error("jabber", "X-FACEBOOK-PLATFORM challenge "
						   "wasn't valid base64: %s\n", challenge);
	
		*msg = g_strdup(_("Invalid response from server"));

		g_free(challenge);
		return JABBER_SASL_STATE_FAIL;
	}
	g_free(challenge);

	/* NULL-terminate the challenge so we can parse it */
	challenge = g_strndup((const gchar *)decoded, decoded_len);
	g_free(decoded);
	purple_debug_misc("jabber", "X-FACEBOOK-PLATFORM decoded "
					  "challenge is %s\n", challenge);

	/* Get method and nonce */
	method = NULL;
	nonce = NULL;
	pairs = g_strsplit(challenge, "&", 0);
	for (i = 0; pairs[i] != NULL; i++) {
		if (g_str_has_prefix(pairs[i], "method=")) {
			g_free(method);
			// TODO: Should url decode this value
			method = g_strdup(strchr(pairs[i], '=') + 1);
		} else if (g_str_has_prefix(pairs[i], "nonce=")) {
			g_free(nonce);
			// TODO: Should url decode this value
			nonce = g_strdup(strchr(pairs[i], '=') + 1);
		}
	}
	g_strfreev(pairs);
	if (!method || !nonce) {
		purple_debug_error("jabber", "X-FACEBOOK-PLATFORM challenge "
						   "is missing method or nonce: %s\n", challenge);
		*msg = g_strdup(_("Invalid response from server"));

		g_free(method);
		g_free(nonce);
		g_free(challenge);
		return JABBER_SASL_STATE_FAIL;
	}
	g_free(challenge);

	request = purple_fbapi_construct_request(purple_connection_get_account(js->gc),
											 method,
											 "v", "1.0",
											 "session_key", purple_connection_get_password(js->gc),
											 "nonce", nonce,
											 NULL);
	g_free(method);
	g_free(nonce);

	purple_debug_misc("jabber", "X-FACEBOOK-PLATFORM response before "
					  "encoding is %s\n", request->str);
	enc_out = purple_base64_encode((const guchar *)request->str, request->len);
	g_string_free(request, TRUE);

	reply = xmlnode_new("response");
	xmlnode_set_namespace(reply, NS_XMPP_SASL);
	xmlnode_insert_data(reply, enc_out, -1);

	g_free(enc_out);

	*response = reply;

	return JABBER_SASL_STATE_CONTINUE;
}