Beispiel #1
0
static void
nexus_got_response_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
{
	MsnNexus *nexus = data;
	MsnSession *session = nexus->session;
	const char *ticket;
	char *response;

	if (resp == NULL) {
		msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Unable to connect"));
		return;
	}

	if (!nexus_parse_collection(nexus, -1,
	                            xmlnode_get_child(resp->xml,
	                                              "Body/RequestSecurityTokenResponseCollection"))) {
		msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Invalid response"));
		return;
	}

	ticket = msn_nexus_get_token_str(nexus, MSN_AUTH_MESSENGER);
	response = msn_rps_encrypt(nexus);
	msn_got_login_params(session, ticket, response);
	g_free(response);
}
Beispiel #2
0
static void
got_header(MsnNexus *nexus,
           const gchar *header)
{
    MsnSession *session = nexus->session;

    if (strstr(header, "HTTP/1.1 200 OK")) {
        char *base, *c;
        char *login_params;

        base  = strstr(header, "Authentication-Info: ");

        if (!base)
            goto parse_error;

        base = strstr(base, "from-PP='");
        base += strlen("from-PP='");
        c = strchr(base, '\'');

        login_params = g_strndup(base, c - base);

        msn_got_login_params(session, login_params);

        g_free(login_params);

        msn_nexus_destroy(nexus);
        session->nexus = NULL;
        return;
    }
    else if (strstr(header, "HTTP/1.1 302")) {
        /* Redirect. */
        char *location, *c;

        location = strstr(header, "Location: ");
        if (!location)
            goto parse_error;
        location = strchr(location, ' ') + 1;

        if ((c = strchr(location, '\r')))
            *c = '\0';

        /* Skip the http:// */
        if ((c = strchr(location, '/')))
            location = c + 2;

        if ((c = strchr(location, '/'))) {
            g_free(nexus->login_path);
            nexus->login_path = g_strdup(c);

            *c = '\0';
        }

        g_free(nexus->login_host);
        nexus->login_host = g_strdup(location);

        pn_info("reconnecting to '%s'", nexus->login_host);
        pn_parser_reset(nexus->parser);
        nexus->parser_state = 0;

        nexus->open_handler = g_signal_connect(nexus->conn, "open", G_CALLBACK(login_open_cb), nexus);
        pn_node_connect(nexus->conn, nexus->login_host, 443);
        return;
    }
    else if (strstr(header, "HTTP/1.1 401 Unauthorized")) {
        const char *tmp;
        gchar *error = NULL;

        if ((tmp = strstr(header, "WWW-Authenticate"))) {
            if ((tmp = strstr(tmp, "cbtxt="))) {
                const char *c;
                char *tmp2;

                tmp += strlen("cbtxt=");

                c = strchr(tmp, '\n');
                if (!c)
                    c = tmp + strlen(tmp);

                tmp2 = g_strndup(tmp, c - tmp);
                error = pn_url_decode(tmp2);
                g_free(tmp2);
                if ((tmp2 = strstr(error, " Do one of the following or try again:")) != NULL)
                    *tmp2 = '\0';
            }
        }

        msn_session_set_error(session, MSN_ERROR_AUTH, error);
        g_free(error);
        return;
    }
    else if (strstr(header, "HTTP/1.1 503 Service Unavailable")) {
        msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
        return;
    }

parse_error:
    msn_session_set_error(session, MSN_ERROR_AUTH, _("nexus parse error"));
}
Beispiel #3
0
static void
nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	MsnNexus *nexus = data;
	MsnSession *session;
	int len;

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

	if (nexus->input_handler == 0)
		/* TODO: Use purple_ssl_input_add()? */
		nexus->input_handler = purple_input_add(nexus->gsc->fd,
			PURPLE_INPUT_READ, nexus_login_written_cb, nexus);


	len = msn_ssl_read(nexus);

	if (len < 0 && errno == EAGAIN)
		return;
	else if (len < 0) {
		purple_input_remove(nexus->input_handler);
		nexus->input_handler = 0;
		g_free(nexus->read_buf);
		nexus->read_buf = NULL;
		nexus->read_len = 0;
		/* TODO: error handling */
		return;
	}

	if (g_strstr_len(nexus->read_buf, nexus->read_len,
			"\r\n\r\n") == NULL)
		return;

	purple_input_remove(nexus->input_handler);
	nexus->input_handler = 0;

	purple_ssl_close(nexus->gsc);
	nexus->gsc = NULL;

	pecan_log ("ssl buffer: [%s]", nexus->read_buf);

	if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL)
	{
		/* Redirect. */
		char *location, *c;

		location = strstr(nexus->read_buf, "Location: ");
		if (location == NULL)
		{
			g_free(nexus->read_buf);
			nexus->read_buf = NULL;
			nexus->read_len = 0;

			return;
		}
		location = strchr(location, ' ') + 1;

		if ((c = strchr(location, '\r')) != NULL)
			*c = '\0';

		/* Skip the http:// */
		if ((c = strchr(location, '/')) != NULL)
			location = c + 2;

		if ((c = strchr(location, '/')) != NULL)
		{
			g_free(nexus->login_path);
			nexus->login_path = g_strdup(c);

			*c = '\0';
		}

		g_free(nexus->login_host);
		nexus->login_host = g_strdup(location);

		nexus->gsc = purple_ssl_connect(session->account,
				nexus->login_host, PURPLE_SSL_DEFAULT_PORT,
				login_connect_cb, login_error_cb, nexus);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL)
	{
		const char *error;

		if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL)
		{
			if ((error = strstr(error, "cbtxt=")) != NULL)
			{
				const char *c;
				char *temp;

				error += strlen("cbtxt=");

				if ((c = strchr(error, '\n')) == NULL)
					c = error + strlen(error);

				temp = g_strndup(error, c - error);
				error = purple_url_decode(temp);
				g_free(temp);
				if ((temp = strstr(error, " Do one of the following or try again:")) != NULL)
					*temp = '\0';
			}
		}

		msn_session_set_error(session, MSN_ERROR_AUTH, error);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 503 Service Unavailable"))
	{
		msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK"))
	{
		char *base, *c;
		char *login_params;

#if 0
		/* All your base are belong to us. */
		base = buffer;

		/* For great cookie! */
		while ((base = strstr(base, "Set-Cookie: ")) != NULL)
		{
			base += strlen("Set-Cookie: ");

			c = strchr(base, ';');

			session->login_cookies =
				g_list_append(session->login_cookies,
							  g_strndup(base, c - base));
		}
#endif

		base  = strstr(nexus->read_buf, "Authentication-Info: ");

		g_return_if_fail(base != NULL);

		base  = strstr(base, "from-PP='");
		base += strlen("from-PP='");
		c     = strchr(base, '\'');

		login_params = g_strndup(base, c - base);

		msn_got_login_params(session, login_params);

		g_free(login_params);

		msn_nexus_destroy(nexus);
		session->nexus = NULL;
		return;
	}

	g_free(nexus->read_buf);
	nexus->read_buf = NULL;
	nexus->read_len = 0;

}